Get the current moon phase with Actionscript3

If your favorite weather data feed does not return a moon phase, you can use a script to generate a number for it, based on the date.

< Demo.
Left: current date.
Right: type in a test date (month-day-year) then click the night sky thumbnail.


I found the original snippet at voidware.com, which I translated into actionscript for use in my flash weather module. The function returns a frame number, which matches the correct moon phase in a range of frames in a movieclip. The shade is a shape tween, so you don’t have to draw all 30 phases as separate frames. In the flash, I’ve also added a dark background that turns lighter as the moon waxes fuller, like a real night sky would.

Just a simple moon looks like this:
moon phases

And here’s a more complex one:
moon phase Ziggo module

The moon shade is the same simple shape tween as the image above, but with a blur filter applied, a brightness of -30%, and blend: multiply.

getMoonPhase function:

//return frame number for moon phase display
function getMoonPhase(yr:Number, m:Number, d:Number):int{
	//based on http://www.voidware.com/moon_phase.htm
	//calculates the moon phase (frames 1-30 )
	// 1: new moon; 16: full moon
    if (m < 3) {
        yr -= 1;
        m += 12;
    }
    //m += 1;
    var c:Number = 365.25*yr;
    var e:Number = 30.6*m;
	//jd is total days elapsed
	//divide by the moon cycle (29.53 days)
    var jd:Number = (c+e+d-694039.09)/29.53;
	//subtract integer to leave fractional part
    jd = jd - int(jd);
	//range fraction from 0-30 and round by adding 0.5
	var frame:int = Math.round(jd*30 + 0.5);
    return frame;
}
//test: september 23, 2002, not a full moon?
//trace("22 sept 02: _phase: "+getMoonPhase(2002, 9, 22)); //<-21 Sept full moon
//trace("17 juli 08: _phase: "+getMoonPhase(2008, 7, 17)); //<-full moon
//trace("9 feb 09: _phase: "+getMoonPhase(2009, 2, 9)); //<-full moon

This function needs separate numbers for year, month and day, which I supply it by getting the system date – but it would be better to get a date out of the actual feed, and parse that for use with the function. Here’s how I get the values and call the function:

//call the function
var ndate = new Date();
var yr = ndate.getFullYear();
var m = int(ndate.getMonth())+1;
var d = ndate.getDate();
trace("moonPhase: "+getMoonPhase(yr, m, d)+", month: "+m+", d: "+d);
var maanframe = getMoonPhase(yr, m, d);

//is it night? show a moon
if(night) {
    weericon.maan.gotoAndStop(maanframe); //sets moon phase
}

To make the moon even more realistic, you could use this technique of using shape tweens for a shade overlay with a photo of the moon, of course.

0

in snippets+

post a commentsave the linkrate as favorite

4 comments

  1. LeeC
    on May 9, 2011 om 01:20 | link

    Don’t know if you’ve noticed, but this code produces incorrect results. For example, today (9th May 2011), this code says the moon is on phase 9. If 16 is a full moon, then 9 would be just over a half moon… which is not how the moon is today.

    If you look at the Wikipedia article on Lunar Phase, you can see a .JPG of the phases in May 2005. According to what I see in the sky right now, we are on the equivalent of something like Thursday 12th or Friday 13th.

  2. on May 9, 2011 om 15:34 | link

    I have commented out the “m+=1″ line, which corrects the problem. The getMoonPhase() function expects a month-number starting with 1 for January, as would happen with an xml-feed or text-input. But in the date-getter-snippet, getMonth() returns numbers starting with 0 for January, and I already compensate right there with “+1″. You can check with the demo and this url: http://www.universetoday.com/20177/moon-phases-2011/

  3. Crissy
    on July 13, 2011 om 09:57 | link

    Thanks for the moon phase code!

    Is there a need to take into account a leap year..do we need to add in another day?

  4. on July 13, 2011 om 10:13 | link

    No need, it seems the formula (see voidware.com) corrects for that.

leave a comment

Your e-mail address will not be made public or shared with others. Required fields are marked with a *

*
*

Optionally, you could use these HTML tags: <b> <cite> <code> <i> <strike> <strong>