Location: PHPKode > scripts > Sun - set, rise, dawn, dusk > sun-set-rise-dawn-dusk/sun.class.php
<?php
/*
  Sunset and sunrise calculation v1.00.0 (10.03.2008)
  by Tomas Kavalek - http://www.kavalek.net
  based on http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
  
--------------------------------------------------------------------------------

  Source:
  	Almanac for Computers, 1990
  	published by Nautical Almanac Office
  	United States Naval Observatory
  	Washington, DC 20392
  
  Inputs:
  	day, month, year:      date of sunrise/sunset
  	latitude, longitude:   location for sunrise/sunset
  	zenith:                Sun's zenith for sunrise/sunset
  	  offical      = 90 degrees 50'
  	  civil        = 96 degrees
  	  nautical     = 102 degrees
  	  astronomical = 108 degrees
  	
  	NOTE: longitude is positive for East and negative for West
  
  
  1. first calculate the day of the year
  
  	N1 = floor(275 * month / 9)
  	N2 = floor((month + 9) / 12)
  	N3 = (1 + floor((year - 4 * floor(year / 4) + 2) / 3))
  	N = N1 - (N2 * N3) + day - 30
  
  2. convert the longitude to hour value and calculate an approximate time
  
  	lngHour = longitude / 15
  	
  	if rising time is desired:
  	  t = N + ((6 - lngHour) / 24)
  	if setting time is desired:
  	  t = N + ((18 - lngHour) / 24)
  
  3. calculate the Sun's mean anomaly
  	
  	M = (0.9856 * t) - 3.289
  
  4. calculate the Sun's true longitude
  	
  	L = M + (1.916 * sin(M)) + (0.020 * sin(2 * M)) + 282.634
  	NOTE: L potentially needs to be adjusted into the range [0,360) by adding/subtracting 360
  
  5a. calculate the Sun's right ascension
  	
  	RA = atan(0.91764 * tan(L))
  	NOTE: RA potentially needs to be adjusted into the range [0,360) by adding/subtracting 360
  
  5b. right ascension value needs to be in the same quadrant as L
  
  	Lquadrant  = (floor( L/90)) * 90
  	RAquadrant = (floor(RA/90)) * 90
  	RA = RA + (Lquadrant - RAquadrant)
  
  5c. right ascension value needs to be converted into hours
  
  	RA = RA / 15
  
  6. calculate the Sun's declination
  
  	sinDec = 0.39782 * sin(L)
  	cosDec = cos(asin(sinDec))
  
  7a. calculate the Sun's local hour angle
  	
  	cosH = (cos(zenith) - (sinDec * sin(latitude))) / (cosDec * cos(latitude))
  	
  	if (cosH >  1) 
  	  the sun never rises on this location (on the specified date)
  	if (cosH < -1)
  	  the sun never sets on this location (on the specified date)
  
  7b. finish calculating H and convert into hours
  	
  	if if rising time is desired:
  	  H = 360 - acos(cosH)
  	if setting time is desired:
  	  H = acos(cosH)
  	
  	H = H / 15
  
  8. calculate local mean time of rising/setting
  	
  	T = H + RA - (0.06571 * t) - 6.622
  
  9. adjust back to UTC
  	
  	UT = T - lngHour
  	NOTE: UT potentially needs to be adjusted into the range [0,24) by adding/subtracting 24
  
  10. convert UT value to local time zone of latitude/longitude
  	
  	localT = UT + localOffset
*/

define("SUNRISE", 0);
define("SUNSET", 1);

class SUN {
  var $timezone;
  var $latitude;
  var $longitude;
  var $zenith;
  var $date;
  var $type;
  var $coords;
  
  function sin($d) {
    return sin(deg2rad($d));
  }

  function cos($d) {
    return cos(deg2rad($d));
  }
  
  function tan($d) {
    return tan(deg2rad($d));
  }

  function atan($x) {
    return rad2deg(atan($x));
  }

  function asin($x) {
    return rad2deg(asin($x));
  }
  
  function acos($x) {
    return rad2deg(acos($x));
  } 

  function set_timezone($timezone) {
    $this->timezone = $timezone;
  }
  
  function set_latitude($latitude) {
    $this->latitude = $this->coords2dec($latitude);
  }
  
  function set_longitude($longitude) {
    $this->longitude = $this->coords2dec($longitude);
  }

  function set_zenith($zenith) {
    $this->zenith = $zenith;
  }

  function set_coords($coords) {
    if(preg_match("/([^\s]+) ([^\s]+)/", $coords, $matches)) {
      $this->set_latitude($this->coords2dec($matches[1]));
      $this->set_longitude($this->coords2dec($matches[2]));
      $this->coords = $coords;
    } else return;
  }

  function get_timezone() {
    return $this->timezone;
  }
  
  function get_latitude() {
    return $this->latitude;
  }
  
  function get_longitude() {
    return $this->longitude;
  }

  function get_zenith() {
    return $this->zenith;
  }

  function get_coords() {
    return $this->coords;
  }

  function coords2dec($coords) {
    if(preg_match("/([0-9]+)°([0-9]+)'([0-9\.]+)\"([NnWwEeSs])/", $coords, $matches)) {
      $const = (strtolower($matches[4]) == "e") || (strtolower($matches[4]) == "n") ? 1 : -1;
      return $const * ($matches[1] + $matches[2] / 60 + $matches[3] / 3600);
    } else return $coords;
  }

  function SUN() {
     $this->zenith = 90 + (50 / 60);
     $this->timezone = date("O") / 100;
  }

  function calculation() {
    $n = (int)date("z", $this->date);

    $lnghour = $this->longitude / 15;

    if($this->type == SUNSET) $t = $n + ((18 - $lnghour) / 24);
    else $t = $n + ((6 - $lnghour) / 24);
    
    $m = (0.9856 * $t) - 3.289;
    
    $l = $m + (1.916 * $this->sin($m)) + (0.020 * $this->sin(2 * $m)) + 282.634;
    $l = fmod($l, 360);
    
    $ra = $this->atan(0.91764 * $this->tan($l));
    $ra = fmod($ra, 360);
    
    $lquadrant = floor($l / 90) * 90;
    $raquadrant = floor($ra / 90) * 90;
    $ra = $ra + ($lquadrant - $raquadrant);
    
    $ra = $ra / 15;
    
    $sindec = 0.39782 * $this->sin($l);
    $cosdec = $this->cos($this->asin($sindec));
    
    $cosh = ($this->cos($this->zenith) - ($sindec * $this->sin($this->latitude))) / ($cosdec * $this->cos($this->latitude));

    if(($this->type == SUNRISE) && ($cosh > 1)) return NULL;
    if(($this->type == SUNSET) && ($cosh < -1)) return NULL;
 
    if($this->type == SUNSET) $h = $this->acos($cosh);
    else $h = 360 - $this->acos($cosh);
    
    $h = $h / 15;
    
    $t = $h + $ra - (0.06571 * $t) - 6.622;
    
    $ut = $t - $lnghour;
    $ut = fmod($ut, 24);
    
    $summertime = date("I", $this->date + 24 * 60 * 60) ? 1 : 0;
   
    $localt = $ut + $this->timezone + $summertime;
    
    return $this->date + $localt * 60 * 60;
  }

  function rise($date = 0) {
    $this->type = SUNRISE;
    $this->date = $date ? $date : mktime(0, 0, 0, date("m"), date("d"), date("Y"));
    return date("H:i", $this->calculation());
  }

  function set($date = 0) {
    $this->type = SUNSET;
    $this->date = $date ? $date : mktime(0, 0, 0, date("m"), date("d"), date("Y"));
    return date("H:i", $this->calculation());
  }
  
  function dawn($date = 0) {
    $this->type = SUNRISE;
    $this->date = $date ? $date : mktime(0, 0, 0, date("m"), date("d"), date("Y"));
    return date("H:i", $this->calculation() - 30 * 60);
  }

  function dusk($date = 0) {
    $this->type = SUNSET;
    $this->date = $date ? $date : mktime(0, 0, 0, date("m"), date("d"), date("Y"));
    return date("H:i", $this->calculation() + 30 * 60);
  }
}
?>
Return current item: Sun - set, rise, dawn, dusk