Matt Hackmann

Calculate Moon Rise and Set in PHP

Posted On
Tags
code
daily
release

If you've been paying attention to my Twitter account, you've probably seen a reference or two about how I've been calculating the positions of astronomical bodies. Well, today I release part of that to you.

Download: Source

The above code is pretty much a direct port of Keith Burnett's implementation here. Outside of porting, my only changes were some code clean up and having the timezone be calculated automatically for the longitude given. This means that you will always get back a time stamp that is local to the point of origin.

How to Use

Moon::calculateMoonTimes(month, day, year, latitude, longitude);

Code: php
  1. <?php
  2. date_default_timezone_set('America/Chicago');
  3. include('moon.php');
  4. print_r(Moon::calculateMoonTimes(6, 28, 2011, 36.754478, -96.110291));
  5. ?>

The above code will output the following result:

Code: output
  1. stdClass Object ( [moonrise] =&gt; 1309246800 [moonset] =&gt; 1309300560 )

Moonrise and moonset, as stated previously, are a Unix time stamp local to the latitude and longitude given.

Comments

Eeki
Eeki

Would it be possible do you to change the code to use DateTime, so 2038 -problem would be avoided?

tipichris
tipichris

Useful code, thanks for sharing this. But it doesn't quite work for me.

You seem to calculate the rise and set times in UTC, but then pass this to mktime. mktime expects a local time. The result is a timestamp which is out by the local offset to UTC, and attempting to format it with date produces an incorrect result.

For example, moon rise at my location today is 11:45 UTC. My timezone is +0100 (UK, daylight saving). Passing 11:45 to mktime produces 1340707500. This then gives

echo date("D M j Y G:i T", 1340707500);

prints Tue, Jun 26 2012 11:45 BST

when actually it is 11:45 UTC, 12:45 BST. The correct timestamp would be 1340711100. To get this you need to pass your calculated times to gmmktime.

I'm also not clear what the timezone calculation is supposed to achieve, but in any event it is too crude to be useful. In reality timezone boundaries do not accurately follow 15 degree parallels, and not all timezone offsets are integer numbers of hours. Something like

$offset = date_offset_get(new DateTime);

might be more reliable.

Pharme552
Pharme552

Very nice site!

Shad Keene
Shad Keene

Do you have an illumination percentage option available?

Thanks!

Leave A Comment