FreeWRL
view release on metacpan or search on metacpan
JS/js/jsdate.c view on Meta::CPAN
#define SecondsPerHour (MinutesPerHour * SecondsPerMinute)
#define SecondsPerMinute 60.0
#ifdef XP_PC
/* Work around msvc double optimization bug by making these runtime values; if
* they're available at compile time, msvc optimizes division by them by
* computing the reciprocal and multiplying instead of dividing - this loses
* when the reciprocal isn't representable in a double.
*/
static jsdouble msPerSecond = 1000.0;
static jsdouble msPerDay = SecondsPerDay * 1000.0;
static jsdouble msPerHour = SecondsPerHour * 1000.0;
static jsdouble msPerMinute = SecondsPerMinute * 1000.0;
#else
#define msPerDay (SecondsPerDay * msPerSecond)
#define msPerHour (SecondsPerHour * msPerSecond)
#define msPerMinute (SecondsPerMinute * msPerSecond)
#define msPerSecond 1000.0
#endif
#define Day(t) floor((t) / msPerDay)
static jsdouble
TimeWithinDay(jsdouble t)
{
jsdouble result;
result = fmod(t, msPerDay);
if (result < 0)
result += msPerDay;
return result;
}
#define DaysInYear(y) ((y) % 4 == 0 && ((y) % 100 || ((y) % 400 == 0)) \
? 366 : 365)
/* math here has to be f.p, because we need
* floor((1968 - 1969) / 4) == -1
*/
#define DayFromYear(y) (365 * ((y)-1970) + floor(((y)-1969)/4.0) \
- floor(((y)-1901)/100.0) + floor(((y)-1601)/400.0))
#define TimeFromYear(y) (DayFromYear(y) * msPerDay)
static jsint
YearFromTime(jsdouble t)
{
jsint lo = (jsint) floor((t / msPerDay) / 366) + 1970;
jsint hi = (jsint) floor((t / msPerDay) / 365) + 1970;
jsint mid;
/* above doesn't work for negative dates... */
if (hi < lo) {
jsint temp = lo;
lo = hi;
hi = temp;
}
/* Use a simple binary search algorithm to find the right
year. This seems like brute force... but the computation
of hi and lo years above lands within one year of the
correct answer for years within a thousand years of
1970; the loop below only requires six iterations
for year 270000. */
while (hi > lo) {
mid = (hi + lo) / 2;
if (TimeFromYear(mid) > t) {
hi = mid - 1;
} else {
if (TimeFromYear(mid) <= t) {
jsint temp = mid + 1;
if (TimeFromYear(temp) > t) {
return mid;
}
lo = mid + 1;
}
}
}
return lo;
}
#define InLeapYear(t) (JSBool) (DaysInYear(YearFromTime(t)) == 366)
#define DayWithinYear(t, year) ((intN) (Day(t) - DayFromYear(year)))
/*
* The following array contains the day of year for the first day of
* each month, where index 0 is January, and day 0 is January 1.
*/
static jsdouble firstDayOfMonth[2][12] = {
{0.0, 31.0, 59.0, 90.0, 120.0, 151.0, 181.0, 212.0, 243.0, 273.0, 304.0, 334.0},
{0.0, 31.0, 60.0, 91.0, 121.0, 152.0, 182.0, 213.0, 244.0, 274.0, 305.0, 335.0}
};
#define DayFromMonth(m, leap) firstDayOfMonth[leap][(intN)m];
static intN
MonthFromTime(jsdouble t)
{
intN d, step;
jsint year = YearFromTime(t);
d = DayWithinYear(t, year);
if (d < (step = 31))
return 0;
step += (InLeapYear(t) ? 29 : 28);
if (d < step)
return 1;
if (d < (step += 31))
return 2;
if (d < (step += 30))
return 3;
if (d < (step += 31))
return 4;
if (d < (step += 30))
return 5;
if (d < (step += 31))
return 6;
if (d < (step += 31))
return 7;
if (d < (step += 30))
return 8;
if (d < (step += 31))
( run in 2.448 seconds using v1.01-cache-2.11-cpan-71847e10f99 )