David Fugate fbb888778d Quite a few modifications have been made to the test harness (website/resources/scripts/global/*)
which have resulted in it being able to run negative test cases which corrupt the global JavaScript
environment.  This lets us enable fifty plus more Sputnik test cases.  Another positive result from
this test harness refactoring is that Opera no longer hangs when running the tests.
2010-11-12 09:27:59 -08:00

342 lines
9.0 KiB
JavaScript

// Copyright 2009 the Sputnik authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
//15.9.1.2 Day Number and Time within Day
function Day(t) {
return Math.floor(t/msPerDay);
}
function TimeWithinDay(t) {
return t%msPerDay;
}
//15.9.1.3 Year Number
function DaysInYear(y){
if(y%4 != 0) return 365;
if(y%4 == 0 && y%100 != 0) return 366;
if(y%100 == 0 && y%400 != 0) return 365;
if(y%400 == 0) return 366;
}
function DayFromYear(y) {
return (365*(y-1970)
+ Math.floor((y-1969)/4)
- Math.floor((y-1901)/100)
+ Math.floor((y-1601)/400));
}
function TimeFromYear(y){
return msPerDay*DayFromYear(y);
}
function YearFromTime(t) {
t = Number(t);
var sign = ( t < 0 ) ? -1 : 1;
var year = ( sign < 0 ) ? 1969 : 1970;
for(var time = 0;;year += sign){
time = TimeFromYear(year);
if(sign > 0 && time > t){
year -= sign;
break;
}
else if(sign < 0 && time <= t){
break;
}
};
return year;
}
function InLeapYear(t){
if(DaysInYear(YearFromTime(t)) == 365)
return 0;
if(DaysInYear(YearFromTime(t)) == 366)
return 1;
}
function DayWithinYear(t) {
return Day(t)-DayFromYear(YearFromTime(t));
}
//15.9.1.4 Month Number
function MonthFromTime(t){
var day = DayWithinYear(t);
var leap = InLeapYear(t);
if((0 <= day) && (day < 31)) return 0;
if((31 <= day) && (day < (59+leap))) return 1;
if(((59+leap) <= day) && (day < (90+leap))) return 2;
if(((90+leap) <= day) && (day < (120+leap))) return 3;
if(((120+leap) <= day) && (day < (151+leap))) return 4;
if(((151+leap) <= day) && (day < (181+leap))) return 5;
if(((181+leap) <= day) && (day < (212+leap))) return 6;
if(((212+leap) <= day) && (day < (243+leap))) return 7;
if(((243+leap) <= day) && (day < (273+leap))) return 8;
if(((273+leap) <= day) && (day < (304+leap))) return 9;
if(((304+leap) <= day) && (day < (334+leap))) return 10;
if(((334+leap) <= day) && (day < (365+leap))) return 11;
}
//15.9.1.5 Date Number
function DateFromTime(t) {
var day = DayWithinYear(t);
var month = MonthFromTime(t);
var leap = InLeapYear(t);
if(month == 0) return day+1;
if(month == 1) return day-30;
if(month == 2) return day-58-leap;
if(month == 3) return day-89-leap;
if(month == 4) return day-119-leap;
if(month == 5) return day-150-leap;
if(month == 6) return day-180-leap;
if(month == 7) return day-211-leap;
if(month == 8) return day-242-leap;
if(month == 9) return day-272-leap;
if(month == 10) return day-303-leap;
if(month == 11) return day-333-leap;
}
//15.9.1.6 Week Day
function WeekDay(t) {
var weekday = (Day(t)+4)%7;
return (weekday < 0 ? 7+weekday : weekday);
}
//15.9.1.9 Daylight Saving Time Adjustment
var LocalTZA = $LocalTZ*msPerHour;
function DaysInMonth(m, leap) {
m = m%12;
//April, June, Sept, Nov
if(m == 3 || m == 5 || m == 8 || m == 10 ) {
return 30;
}
//Jan, March, May, July, Aug, Oct, Dec
if(m == 0 || m == 2 || m == 4 || m == 6 || m == 7 || m == 9 || m == 11){
return 31;
}
//Feb
return 28+leap;
}
function GetSundayInMonth(t, m, count){
var year = YearFromTime(t);
var leap = InLeapYear(t);
var day = 0;
if(m >= 1) day += DaysInMonth(0, leap);
if(m >= 2) day += DaysInMonth(1, leap);
if(m >= 3) day += DaysInMonth(2, leap);
if(m >= 4) day += DaysInMonth(3, leap);
if(m >= 5) day += DaysInMonth(4, leap);
if(m >= 6) day += DaysInMonth(5, leap);
if(m >= 7) day += DaysInMonth(6, leap);
if(m >= 8) day += DaysInMonth(7, leap);
if(m >= 9) day += DaysInMonth(8, leap);
if(m >= 10) day += DaysInMonth(9, leap);
if(m >= 11) day += DaysInMonth(10, leap);
var month_start = TimeFromYear(year)+day*msPerDay;
var sunday = 0;
if(count === "last"){
for(var last_sunday = month_start+DaysInMonth(m, leap)*msPerDay;
WeekDay(last_sunday)>0;
last_sunday -= msPerDay
){};
sunday = last_sunday;
}
else {
for(var first_sunday = month_start;
WeekDay(first_sunday)>0;
first_sunday += msPerDay
){};
sunday = first_sunday+7*msPerDay*(count-1);
}
return sunday;
}
function DaylightSavingTA(t) {
t = t-LocalTZA;
var DST_start = GetSundayInMonth(t, $DST_start_month, $DST_start_sunday)
+$DST_start_hour*msPerHour
+$DST_start_minutes*msPerMinute;
var k = new Date(DST_start);
var DST_end = GetSundayInMonth(t, $DST_end_month, $DST_end_sunday)
+$DST_end_hour*msPerHour
+$DST_end_minutes*msPerMinute;
if ( t >= DST_start && t < DST_end ) {
return msPerHour;
} else {
return 0;
}
}
//15.9.1.9 Local Time
function LocalTime(t){
return t+LocalTZA+DaylightSavingTA(t);
}
function UTC(t) {
return t-LocalTZA-DaylightSavingTA(t-LocalTZA);
}
//15.9.1.10 Hours, Minutes, Second, and Milliseconds
function HourFromTime(t){
return Math.floor(t/msPerHour)%HoursPerDay;
}
function MinFromTime(t){
return Math.floor(t/msPerMinute)%MinutesPerHour;
}
function SecFromTime(t){
return Math.floor(t/msPerSecond)%SecondsPerMinute;
}
function msFromTime(t){
return t%msPerSecond;
}
//15.9.1.11 MakeTime (hour, min, sec, ms)
function MakeTime(hour, min, sec, ms){
if ( !isFinite(hour) || !isFinite(min) || !isFinite(sec) || !isFinite(ms)) {
return Number.NaN;
}
hour = ToInteger(hour);
min = ToInteger(min);
sec = ToInteger(sec);
ms = ToInteger(ms);
return ((hour*msPerHour) + (min*msPerMinute) + (sec*msPerSecond) + ms);
}
//15.9.1.12 MakeDay (year, month, date)
function MakeDay(year, month, date) {
if ( !isFinite(year) || !isFinite(month) || !isFinite(date)) {
return Number.NaN;
}
year = ToInteger(year);
month = ToInteger(month);
date = ToInteger(date );
var result5 = year + Math.floor(month/12);
var result6 = month%12;
var sign = ( year < 1970 ) ? -1 : 1;
var t = ( year < 1970 ) ? 1 : 0;
var y = ( year < 1970 ) ? 1969 : 1970;
if( sign == -1 ){
for ( y = 1969; y >= year; y += sign ) {
t += sign * DaysInYear(y)*msPerDay;
}
} else {
for ( y = 1970 ; y < year; y += sign ) {
t += sign * DaysInYear(y)*msPerDay;
}
}
var leap = 0;
for ( var m = 0; m < month; m++ ) {
//if year is changed, than we need to recalculate leep
leap = InLeapYear(t);
t += DaysInMonth(m, leap)*msPerDay;
}
if ( YearFromTime(t) != result5 ) {
return Number.NaN;
}
if ( MonthFromTime(t) != result6 ) {
return Number.NaN;
}
if ( DateFromTime(t) != 1 ) {
return Number.NaN;
}
return Day(t)+date-1;
}
//15.9.1.13 MakeDate (day, time)
function MakeDate( day, time ) {
if(!isFinite(day) || !isFinite(time)) {
return Number.NaN;
}
return day*msPerDay+time;
}
//15.9.1.14 TimeClip (time)
function TimeClip(time) {
if(!isFinite(time) || Math.abs(time) > 8.64e15){
return Number.NaN;
}
return ToInteger(time);
}
//Test Functions
function ConstructDate(year, month, date, hours, minutes, seconds, ms){
/*
* 1. Call ToNumber(year)
* 2. Call ToNumber(month)
* 3. If date is supplied use ToNumber(date); else use 1
* 4. If hours is supplied use ToNumber(hours); else use 0
* 5. If minutes is supplied use ToNumber(minutes); else use 0
* 6. If seconds is supplied use ToNumber(seconds); else use 0
* 7. If ms is supplied use ToNumber(ms); else use 0
* 8. If Result(1) is not NaN and 0 <= ToInteger(Result(1)) <= 99, Result(8) is
* 1900+ToInteger(Result(1)); otherwise, Result(8) is Result(1)
* 9. Compute MakeDay(Result(8), Result(2), Result(3))
* 10. Compute MakeTime(Result(4), Result(5), Result(6), Result(7))
* 11. Compute MakeDate(Result(9), Result(10))
* 12. Set the [[Value]] property of the newly constructed object to TimeClip(UTC(Result(11)))
*/
var r1 = Number(year);
var r2 = Number(month);
var r3 = ((date && arguments.length > 2) ? Number(date) : 1);
var r4 = ((hours && arguments.length > 3) ? Number(hours) : 0);
var r5 = ((minutes && arguments.length > 4) ? Number(minutes) : 0);
var r6 = ((seconds && arguments.length > 5) ? Number(seconds) : 0);
var r7 = ((ms && arguments.length > 6) ? Number(ms) : 0);
var r8 = r1;
if(!isNaN(r1) && (0 <= ToInteger(r1)) && (ToInteger(r1) <= 99))
r8 = 1900+r1;
var r9 = MakeDay(r8, r2, r3);
var r10 = MakeTime(r4, r5, r6, r7);
var r11 = MakeDate(r9, r10);
return TimeClip(UTC(r11));
}
//the following values are normally generated by the sputnik.py driver
// for now, we'll just use 0 for everything
/*
var $LocalTZ=-8;
var $DST_start_month=2;
var $DST_start_sunday='first';
var $DST_start_hour=2;
var $DST_start_minutes=0;
var $DST_end_month=10;
var $DST_end_sunday='first';
var $DST_end_hour=2;
var $DST_end_minutes=0;
*/