Posted on Tuesday 25 January 2005
Here is the issue I had: I was working with my timeline code and if you zoom in a lot with a very short year span, you can notice the headers and ticks don't line up exactly with the periods. I traced the issue to the simple fact that years and months don't have the same number of days. The renderer was assuming that years have exactly 365.2425 days in them, months have exactly 365.2425/12 days in them, and then it would use this assumption in rendering the ticks and headers, while periods used Date.UTC to assign them a beginning and end position between 0 and 1. Well with 100 years, the errors tend to cancel out, but with 4 years, it would produce noticeable rendering errors.
So I figured there was two solutions:
- correcting for variable length years and months in the renderer. That's bad. The renderer is already looping through several multi-dimensional arrays and moving about 200 movieclips every 17 milliseconds, so pushing it any further doesn't sound too good.
- Creating a fake Date.UTC function that would correct for variable length. In essence, it gives you the number of seconds since January 1st, 1970, assuming that every year has 365.2425 days and every month has 365.2425/12 days. I figured it would be very useful too if you ever need to create date comparisons so here it is:
var _monthLengths:Array = [31,28,31,30,31,30,31,31,30,31,30,31];
/**
* Calculates a normalized UTC
*
* @param year The year
* @param month The month, (0 based index)
* @param day The day (1 based index)
*/
function normalizedUTC(year:Number, month:Number, day:Number):Number
{
var yearoffset = year - 1970;
if(month != 1)
{
var monthoffset = ((day - 1)/_monthLengths[month]);
}
else
{
//Correct for february
var monthoffset = (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) ?
((day - 1)/29) :
((day - 1)/28);
}
//31556952000 = 365.2425*24*60*60*1000
return (yearoffset + (month + monthoffset)/12)*31556952000;
}


