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:

And here’s a more complex one:

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.
4 comments
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.
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/
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?
No need, it seems the formula (see voidware.com) corrects for that.
In snippets:
Featured projects:
Most popular:
RSS Links