mirror of https://github.com/svaarala/duktape.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
4.0 KiB
152 lines
4.0 KiB
/*---
|
|
{
|
|
"slow": true
|
|
}
|
|
---*/
|
|
|
|
var ms_day = 24 * 60 * 60 * 1000;
|
|
|
|
var days_in_month_noleap = [
|
|
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
|
];
|
|
|
|
var days_in_month_leap = [
|
|
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
|
];
|
|
|
|
function isLeapYear(x) {
|
|
if (Math.floor(x) !== x) {
|
|
throw new Error('unexpected input: ' + x);
|
|
}
|
|
|
|
if ((x % 4) != 0) {
|
|
return false;
|
|
}
|
|
if ((x % 100) != 0) {
|
|
return true;
|
|
}
|
|
if ((x % 400) != 0) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*===
|
|
brute force conversion test
|
|
===*/
|
|
|
|
/* Brute force back and forth conversion test for each start-of-month
|
|
* for years in the range [-10000, 10000].
|
|
*
|
|
* Testing the entire E5 valid range (+/- 100e6 days from Jan 1, 1970)
|
|
* takes ~4 seconds V8, but with Duktape running under valgrind it
|
|
* takes way too long, so we only test a shorter range here and rely
|
|
* on spot checks in other parts of the range.
|
|
*/
|
|
|
|
function bruteForceConversionTest() {
|
|
var timeval;
|
|
var year, month;
|
|
var dt;
|
|
var isLeap;
|
|
var dayNumber;
|
|
var dayLimit;
|
|
|
|
function msg(x) {
|
|
return 'brute force conversion test failed: ' +
|
|
x + ' (year=' + year + ', month=' + month +
|
|
', dayNumber=' + dayNumber + ', timeval=' + timeval + ')';
|
|
}
|
|
|
|
function testYearAndMonth() {
|
|
// Date from UTC breakdown; note that using Date.UTC() is a bad idea
|
|
// because it assumes years 0-99 mean years 1900-1999.
|
|
//
|
|
// dt = new Date(Date.UTC(year, month /*zero-based month*/, 1, 0, 0, 0, 0));
|
|
//
|
|
// Also note that if you set fields individually, and any intermediate
|
|
// timestamp is out of 'E5 range' (i.e. will cause TimeClip() to return
|
|
// a NaN), the internal time value will become NaN and won't recover to a
|
|
// valid value even if another setter call would make the time valid again.
|
|
// To avoid this issue, set year last.
|
|
|
|
/* This would be one alternative (slower):
|
|
dt = new Date(0);
|
|
dt.setUTCMilliseconds(0);
|
|
dt.setUTCSeconds(0);
|
|
dt.setUTCMinutes(0);
|
|
dt.setUTCHours(0);
|
|
dt.setUTCDate(1);
|
|
dt.setUTCMonth(month);
|
|
dt.setUTCFullYear(year);
|
|
*/
|
|
|
|
dt = new Date(Date.UTC(year, month /*zero-based month*/, 1, 0, 0, 0, 0));
|
|
dt.setUTCFullYear(year); // fix Date if year in [0,99]
|
|
|
|
if (dt.getTime() !== timeval) {
|
|
throw new Error(msg('getTime !== timeVal: ' + dt.getTime() + ' vs ' + timeval));
|
|
}
|
|
if (dt.getUTCFullYear() !== year) {
|
|
throw new Error(msg('getUTCFullYear !== year'));
|
|
}
|
|
if (dt.getUTCMonth() !== month) {
|
|
throw new Error(msg('getUTCMonth !== month'));
|
|
}
|
|
if (dt.getUTCDate() !== 1) {
|
|
throw new Error(msg('getUTCDate !== 1'));
|
|
}
|
|
}
|
|
|
|
timeval = 0;
|
|
dayNumber = 0;
|
|
dayLimit = 2933263; // Mon, 01 Jan 10001 00:00:00 GMT
|
|
year = 1970; month = 0;
|
|
|
|
for (;;) {
|
|
if (dayNumber > dayLimit) {
|
|
break;
|
|
}
|
|
|
|
testYearAndMonth();
|
|
|
|
isLeap = isLeapYear(year);
|
|
timeval += (isLeap ? days_in_month_leap : days_in_month_noleap)[month] * ms_day;
|
|
dayNumber += (isLeap ? days_in_month_leap : days_in_month_noleap)[month];
|
|
|
|
month++;
|
|
if (month == 12) {
|
|
year++;
|
|
month = 0;
|
|
}
|
|
}
|
|
|
|
timeval = 0;
|
|
dayNumber = 0;
|
|
dayLimit = -4371953; // Sat, 01 Jan -10000 00:00:00 GMT
|
|
year = 1970; month = 0;
|
|
for (;;) {
|
|
if (dayNumber < dayLimit) {
|
|
break;
|
|
}
|
|
|
|
testYearAndMonth();
|
|
|
|
month--;
|
|
if (month == -1) {
|
|
year--;
|
|
month = 11;
|
|
}
|
|
|
|
isLeap = isLeapYear(year);
|
|
timeval -= (isLeap ? days_in_month_leap : days_in_month_noleap)[month] * ms_day;
|
|
dayNumber -= (isLeap ? days_in_month_leap : days_in_month_noleap)[month];
|
|
}
|
|
}
|
|
|
|
try {
|
|
print('brute force conversion test');
|
|
bruteForceConversionTest();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|