michael@0: /// Copyright (c) 2012 Ecma International. All rights reserved. michael@0: /// Ecma International makes this code available under the terms and conditions set michael@0: /// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the michael@0: /// "Use Terms"). Any redistribution of this code must retain the above michael@0: /// copyright and this notice and otherwise comply with the Use Terms. michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: function compareArray(aExpected, aActual) { michael@0: if (aActual.length != aExpected.length) { michael@0: return false; michael@0: } michael@0: michael@0: aExpected.sort(); michael@0: aActual.sort(); michael@0: michael@0: var s; michael@0: for (var i = 0; i < aExpected.length; i++) { michael@0: if (aActual[i] !== aExpected[i]) { michael@0: return false; michael@0: } michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: function arrayContains(arr, expected) { michael@0: var found; michael@0: for (var i = 0; i < expected.length; i++) { michael@0: found = false; michael@0: for (var j = 0; j < arr.length; j++) { michael@0: if (expected[i] === arr[j]) { michael@0: found = true; michael@0: break; michael@0: } michael@0: } michael@0: if (!found) { michael@0: return false; michael@0: } michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: var supportsArrayIndexGettersOnArrays = undefined; michael@0: function fnSupportsArrayIndexGettersOnArrays() { michael@0: if (typeof supportsArrayIndexGettersOnArrays !== "undefined") { michael@0: return supportsArrayIndexGettersOnArrays; michael@0: } michael@0: michael@0: supportsArrayIndexGettersOnArrays = false; michael@0: michael@0: if (fnExists(Object.defineProperty)) { michael@0: var arr = []; michael@0: Object.defineProperty(arr, "0", { michael@0: get: function() { michael@0: supportsArrayIndexGettersOnArrays = true; michael@0: return 0; michael@0: } michael@0: }); michael@0: var res = arr[0]; michael@0: } michael@0: michael@0: return supportsArrayIndexGettersOnArrays; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: var supportsArrayIndexGettersOnObjects = undefined; michael@0: function fnSupportsArrayIndexGettersOnObjects() { michael@0: if (typeof supportsArrayIndexGettersOnObjects !== "undefined") michael@0: return supportsArrayIndexGettersOnObjects; michael@0: michael@0: supportsArrayIndexGettersOnObjects = false; michael@0: michael@0: if (fnExists(Object.defineProperty)) { michael@0: var obj = {}; michael@0: Object.defineProperty(obj, "0", { michael@0: get: function() { michael@0: supportsArrayIndexGettersOnObjects = true; michael@0: return 0; michael@0: } michael@0: }); michael@0: var res = obj[0]; michael@0: } michael@0: michael@0: return supportsArrayIndexGettersOnObjects; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: function ConvertToFileUrl(pathStr) { michael@0: return "file:" + pathStr.replace(/\\/g, "/"); michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: function fnExists(/*arguments*/) { michael@0: for (var i = 0; i < arguments.length; i++) { michael@0: if (typeof (arguments[i]) !== "function") return false; michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: var __globalObject = Function("return this;")(); michael@0: function fnGlobalObject() { michael@0: return __globalObject; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: function fnSupportsStrict() { michael@0: "use strict"; michael@0: try { michael@0: eval('with ({}) {}'); michael@0: return false; michael@0: } catch (e) { michael@0: return true; michael@0: } michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: //Verify all attributes specified data property of given object: michael@0: //value, writable, enumerable, configurable michael@0: //If all attribute values are expected, return true, otherwise, return false michael@0: function dataPropertyAttributesAreCorrect(obj, michael@0: name, michael@0: value, michael@0: writable, michael@0: enumerable, michael@0: configurable) { michael@0: var attributesCorrect = true; michael@0: michael@0: if (obj[name] !== value) { michael@0: if (typeof obj[name] === "number" && michael@0: isNaN(obj[name]) && michael@0: typeof value === "number" && michael@0: isNaN(value)) { michael@0: // keep empty michael@0: } else { michael@0: attributesCorrect = false; michael@0: } michael@0: } michael@0: michael@0: try { michael@0: if (obj[name] === "oldValue") { michael@0: obj[name] = "newValue"; michael@0: } else { michael@0: obj[name] = "OldValue"; michael@0: } michael@0: } catch (we) { michael@0: } michael@0: michael@0: var overwrited = false; michael@0: if (obj[name] !== value) { michael@0: if (typeof obj[name] === "number" && michael@0: isNaN(obj[name]) && michael@0: typeof value === "number" && michael@0: isNaN(value)) { michael@0: // keep empty michael@0: } else { michael@0: overwrited = true; michael@0: } michael@0: } michael@0: if (overwrited !== writable) { michael@0: attributesCorrect = false; michael@0: } michael@0: michael@0: var enumerated = false; michael@0: for (var prop in obj) { michael@0: if (obj.hasOwnProperty(prop) && prop === name) { michael@0: enumerated = true; michael@0: } michael@0: } michael@0: michael@0: if (enumerated !== enumerable) { michael@0: attributesCorrect = false; michael@0: } michael@0: michael@0: michael@0: var deleted = false; michael@0: michael@0: try { michael@0: delete obj[name]; michael@0: } catch (de) { michael@0: } michael@0: if (!obj.hasOwnProperty(name)) { michael@0: deleted = true; michael@0: } michael@0: if (deleted !== configurable) { michael@0: attributesCorrect = false; michael@0: } michael@0: michael@0: return attributesCorrect; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: //Verify all attributes specified accessor property of given object: michael@0: //get, set, enumerable, configurable michael@0: //If all attribute values are expected, return true, otherwise, return false michael@0: function accessorPropertyAttributesAreCorrect(obj, michael@0: name, michael@0: get, michael@0: set, michael@0: setVerifyHelpProp, michael@0: enumerable, michael@0: configurable) { michael@0: var attributesCorrect = true; michael@0: michael@0: if (get !== undefined) { michael@0: if (obj[name] !== get()) { michael@0: if (typeof obj[name] === "number" && michael@0: isNaN(obj[name]) && michael@0: typeof get() === "number" && michael@0: isNaN(get())) { michael@0: // keep empty michael@0: } else { michael@0: attributesCorrect = false; michael@0: } michael@0: } michael@0: } else { michael@0: if (obj[name] !== undefined) { michael@0: attributesCorrect = false; michael@0: } michael@0: } michael@0: michael@0: try { michael@0: var desc = Object.getOwnPropertyDescriptor(obj, name); michael@0: if (typeof desc.set === "undefined") { michael@0: if (typeof set !== "undefined") { michael@0: attributesCorrect = false; michael@0: } michael@0: } else { michael@0: obj[name] = "toBeSetValue"; michael@0: if (obj[setVerifyHelpProp] !== "toBeSetValue") { michael@0: attributesCorrect = false; michael@0: } michael@0: } michael@0: } catch (se) { michael@0: throw se; michael@0: } michael@0: michael@0: michael@0: var enumerated = false; michael@0: for (var prop in obj) { michael@0: if (obj.hasOwnProperty(prop) && prop === name) { michael@0: enumerated = true; michael@0: } michael@0: } michael@0: michael@0: if (enumerated !== enumerable) { michael@0: attributesCorrect = false; michael@0: } michael@0: michael@0: michael@0: var deleted = false; michael@0: try { michael@0: delete obj[name]; michael@0: } catch (de) { michael@0: throw de; michael@0: } michael@0: if (!obj.hasOwnProperty(name)) { michael@0: deleted = true; michael@0: } michael@0: if (deleted !== configurable) { michael@0: attributesCorrect = false; michael@0: } michael@0: michael@0: return attributesCorrect; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: var NotEarlyErrorString = "NotEarlyError"; michael@0: var EarlyErrorRePat = "^((?!" + NotEarlyErrorString + ").)*$"; michael@0: var NotEarlyError = new Error(NotEarlyErrorString); michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // Copyright 2009 the Sputnik authors. All rights reserved. michael@0: // This code is governed by the BSD license found in the LICENSE file. michael@0: michael@0: function Test262Error(message) { michael@0: if (message) this.message = message; michael@0: } michael@0: michael@0: Test262Error.prototype.toString = function () { michael@0: return "Test262 Error: " + this.message; michael@0: }; michael@0: michael@0: function testFailed(message) { michael@0: throw new Test262Error(message); michael@0: } michael@0: michael@0: michael@0: function testPrint(message) { michael@0: michael@0: } michael@0: michael@0: michael@0: //adaptors for Test262 framework michael@0: function $PRINT(message) { michael@0: michael@0: } michael@0: michael@0: function $INCLUDE(message) { } michael@0: function $ERROR(message) { michael@0: testFailed(message); michael@0: } michael@0: michael@0: function $FAIL(message) { michael@0: testFailed(message); michael@0: } michael@0: michael@0: michael@0: michael@0: //Sputnik library definitions michael@0: //Ultimately these should be namespaced some how and only made michael@0: //available to tests that explicitly include them. michael@0: //For now, we just define the globally michael@0: michael@0: //math_precision.js michael@0: // Copyright 2009 the Sputnik authors. All rights reserved. michael@0: // This code is governed by the BSD license found in the LICENSE file. michael@0: michael@0: function getPrecision(num) { michael@0: //TODO: Create a table of prec's, michael@0: // because using Math for testing Math isn't that correct. michael@0: michael@0: var log2num = Math.log(Math.abs(num)) / Math.LN2; michael@0: var pernum = Math.ceil(log2num); michael@0: return (2 * Math.pow(2, -52 + pernum)); michael@0: //return(0); michael@0: } michael@0: michael@0: michael@0: //math_isequal.js michael@0: // Copyright 2009 the Sputnik authors. All rights reserved. michael@0: // This code is governed by the BSD license found in the LICENSE file. michael@0: michael@0: var prec; michael@0: function isEqual(num1, num2) { michael@0: if ((num1 === Infinity) && (num2 === Infinity)) { michael@0: return (true); michael@0: } michael@0: if ((num1 === -Infinity) && (num2 === -Infinity)) { michael@0: return (true); michael@0: } michael@0: prec = getPrecision(Math.min(Math.abs(num1), Math.abs(num2))); michael@0: return (Math.abs(num1 - num2) <= prec); michael@0: //return(num1 === num2); michael@0: } michael@0: michael@0: //numeric_conversion.js michael@0: // Copyright 2009 the Sputnik authors. All rights reserved. michael@0: // This code is governed by the BSD license found in the LICENSE file. michael@0: michael@0: function ToInteger(p) { michael@0: var x = Number(p); michael@0: michael@0: if (isNaN(x)) { michael@0: return +0; michael@0: } michael@0: michael@0: if ((x === +0) michael@0: || (x === -0) michael@0: || (x === Number.POSITIVE_INFINITY) michael@0: || (x === Number.NEGATIVE_INFINITY)) { michael@0: return x; michael@0: } michael@0: michael@0: var sign = (x < 0) ? -1 : 1; michael@0: michael@0: return (sign * Math.floor(Math.abs(x))); michael@0: } michael@0: michael@0: //Date_constants.js michael@0: // Copyright 2009 the Sputnik authors. All rights reserved. michael@0: // This code is governed by the BSD license found in the LICENSE file. michael@0: michael@0: var HoursPerDay = 24; michael@0: var MinutesPerHour = 60; michael@0: var SecondsPerMinute = 60; michael@0: michael@0: var msPerDay = 86400000; michael@0: var msPerSecond = 1000; michael@0: var msPerMinute = 60000; michael@0: var msPerHour = 3600000; michael@0: michael@0: var date_1899_end = -2208988800001; michael@0: var date_1900_start = -2208988800000; michael@0: var date_1969_end = -1; michael@0: var date_1970_start = 0; michael@0: var date_1999_end = 946684799999; michael@0: var date_2000_start = 946684800000; michael@0: var date_2099_end = 4102444799999; michael@0: var date_2100_start = 4102444800000; michael@0: michael@0: // Copyright 2009 the Sputnik authors. All rights reserved. michael@0: // This code is governed by the BSD license found in the LICENSE file. michael@0: michael@0: //the following values are normally generated by the sputnik.py driver michael@0: var $LocalTZ, michael@0: $DST_start_month, michael@0: $DST_start_sunday, michael@0: $DST_start_hour, michael@0: $DST_start_minutes, michael@0: $DST_end_month, michael@0: $DST_end_sunday, michael@0: $DST_end_hour, michael@0: $DST_end_minutes; michael@0: michael@0: (function () { michael@0: /** michael@0: * Finds the first date, starting from |start|, where |predicate| michael@0: * holds. michael@0: */ michael@0: var findNearestDateBefore = function(start, predicate) { michael@0: var current = start; michael@0: var month = 1000 * 60 * 60 * 24 * 30; michael@0: for (var step = month; step > 0; step = Math.floor(step / 3)) { michael@0: if (!predicate(current)) { michael@0: while (!predicate(current)) michael@0: current = new Date(current.getTime() + step); michael@0: current = new Date(current.getTime() - step); michael@0: } michael@0: } michael@0: while (!predicate(current)) { michael@0: current = new Date(current.getTime() + 1); michael@0: } michael@0: return current; michael@0: }; michael@0: michael@0: var juneDate = new Date(2000, 5, 20, 0, 0, 0, 0); michael@0: var decemberDate = new Date(2000, 11, 20, 0, 0, 0, 0); michael@0: var juneOffset = juneDate.getTimezoneOffset(); michael@0: var decemberOffset = decemberDate.getTimezoneOffset(); michael@0: var isSouthernHemisphere = (juneOffset > decemberOffset); michael@0: var winterTime = isSouthernHemisphere ? juneDate : decemberDate; michael@0: var summerTime = isSouthernHemisphere ? decemberDate : juneDate; michael@0: michael@0: var dstStart = findNearestDateBefore(winterTime, function (date) { michael@0: return date.getTimezoneOffset() == summerTime.getTimezoneOffset(); michael@0: }); michael@0: $DST_start_month = dstStart.getMonth(); michael@0: $DST_start_sunday = dstStart.getDate() > 15 ? '"last"' : '"first"'; michael@0: $DST_start_hour = dstStart.getHours(); michael@0: $DST_start_minutes = dstStart.getMinutes(); michael@0: michael@0: var dstEnd = findNearestDateBefore(summerTime, function (date) { michael@0: return date.getTimezoneOffset() == winterTime.getTimezoneOffset(); michael@0: }); michael@0: $DST_end_month = dstEnd.getMonth(); michael@0: $DST_end_sunday = dstEnd.getDate() > 15 ? '"last"' : '"first"'; michael@0: $DST_end_hour = dstEnd.getHours(); michael@0: $DST_end_minutes = dstEnd.getMinutes(); michael@0: michael@0: return; michael@0: })(); michael@0: michael@0: michael@0: //Date.library.js michael@0: // Copyright 2009 the Sputnik authors. All rights reserved. michael@0: // This code is governed by the BSD license found in the LICENSE file. michael@0: michael@0: //15.9.1.2 Day Number and Time within Day michael@0: function Day(t) { michael@0: return Math.floor(t/msPerDay); michael@0: } michael@0: michael@0: function TimeWithinDay(t) { michael@0: return t%msPerDay; michael@0: } michael@0: michael@0: //15.9.1.3 Year Number michael@0: function DaysInYear(y){ michael@0: if(y%4 != 0) return 365; michael@0: if(y%4 == 0 && y%100 != 0) return 366; michael@0: if(y%100 == 0 && y%400 != 0) return 365; michael@0: if(y%400 == 0) return 366; michael@0: } michael@0: michael@0: function DayFromYear(y) { michael@0: return (365*(y-1970) michael@0: + Math.floor((y-1969)/4) michael@0: - Math.floor((y-1901)/100) michael@0: + Math.floor((y-1601)/400)); michael@0: } michael@0: michael@0: function TimeFromYear(y){ michael@0: return msPerDay*DayFromYear(y); michael@0: } michael@0: michael@0: function YearFromTime(t) { michael@0: t = Number(t); michael@0: var sign = ( t < 0 ) ? -1 : 1; michael@0: var year = ( sign < 0 ) ? 1969 : 1970; michael@0: michael@0: for(var time = 0;;year += sign){ michael@0: time = TimeFromYear(year); michael@0: michael@0: if(sign > 0 && time > t){ michael@0: year -= sign; michael@0: break; michael@0: } michael@0: else if(sign < 0 && time <= t){ michael@0: break; michael@0: } michael@0: }; michael@0: return year; michael@0: } michael@0: michael@0: function InLeapYear(t){ michael@0: if(DaysInYear(YearFromTime(t)) == 365) michael@0: return 0; michael@0: michael@0: if(DaysInYear(YearFromTime(t)) == 366) michael@0: return 1; michael@0: } michael@0: michael@0: function DayWithinYear(t) { michael@0: return Day(t)-DayFromYear(YearFromTime(t)); michael@0: } michael@0: michael@0: //15.9.1.4 Month Number michael@0: function MonthFromTime(t){ michael@0: var day = DayWithinYear(t); michael@0: var leap = InLeapYear(t); michael@0: michael@0: if((0 <= day) && (day < 31)) return 0; michael@0: if((31 <= day) && (day < (59+leap))) return 1; michael@0: if(((59+leap) <= day) && (day < (90+leap))) return 2; michael@0: if(((90+leap) <= day) && (day < (120+leap))) return 3; michael@0: if(((120+leap) <= day) && (day < (151+leap))) return 4; michael@0: if(((151+leap) <= day) && (day < (181+leap))) return 5; michael@0: if(((181+leap) <= day) && (day < (212+leap))) return 6; michael@0: if(((212+leap) <= day) && (day < (243+leap))) return 7; michael@0: if(((243+leap) <= day) && (day < (273+leap))) return 8; michael@0: if(((273+leap) <= day) && (day < (304+leap))) return 9; michael@0: if(((304+leap) <= day) && (day < (334+leap))) return 10; michael@0: if(((334+leap) <= day) && (day < (365+leap))) return 11; michael@0: } michael@0: michael@0: //15.9.1.5 Date Number michael@0: function DateFromTime(t) { michael@0: var day = DayWithinYear(t); michael@0: var month = MonthFromTime(t); michael@0: var leap = InLeapYear(t); michael@0: michael@0: if(month == 0) return day+1; michael@0: if(month == 1) return day-30; michael@0: if(month == 2) return day-58-leap; michael@0: if(month == 3) return day-89-leap; michael@0: if(month == 4) return day-119-leap; michael@0: if(month == 5) return day-150-leap; michael@0: if(month == 6) return day-180-leap; michael@0: if(month == 7) return day-211-leap; michael@0: if(month == 8) return day-242-leap; michael@0: if(month == 9) return day-272-leap; michael@0: if(month == 10) return day-303-leap; michael@0: if(month == 11) return day-333-leap; michael@0: } michael@0: michael@0: //15.9.1.6 Week Day michael@0: function WeekDay(t) { michael@0: var weekday = (Day(t)+4)%7; michael@0: return (weekday < 0 ? 7+weekday : weekday); michael@0: } michael@0: michael@0: //15.9.1.9 Daylight Saving Time Adjustment michael@0: $LocalTZ = (new Date()).getTimezoneOffset() / -60; michael@0: if (DaylightSavingTA((new Date()).valueOf()) !== 0) { michael@0: $LocalTZ -= 1; michael@0: } michael@0: var LocalTZA = $LocalTZ*msPerHour; michael@0: michael@0: function DaysInMonth(m, leap) { michael@0: m = m%12; michael@0: michael@0: //April, June, Sept, Nov michael@0: if(m == 3 || m == 5 || m == 8 || m == 10 ) { michael@0: return 30; michael@0: } michael@0: michael@0: //Jan, March, May, July, Aug, Oct, Dec michael@0: if(m == 0 || m == 2 || m == 4 || m == 6 || m == 7 || m == 9 || m == 11){ michael@0: return 31; michael@0: } michael@0: michael@0: //Feb michael@0: return 28+leap; michael@0: } michael@0: michael@0: function GetSundayInMonth(t, m, count){ michael@0: var year = YearFromTime(t); michael@0: var tempDate; michael@0: michael@0: if (count==='"first"') { michael@0: for (var d=1; d <= DaysInMonth(m, InLeapYear(t)); d++) { michael@0: tempDate = new Date(year, m, d); michael@0: if (tempDate.getDay()===0) { michael@0: return tempDate.valueOf(); michael@0: } michael@0: } michael@0: } else if(count==='"last"') { michael@0: for (var d=DaysInMonth(m, InLeapYear(t)); d>0; d--) { michael@0: tempDate = new Date(year, m, d); michael@0: if (tempDate.getDay()===0) { michael@0: return tempDate.valueOf(); michael@0: } michael@0: } michael@0: } michael@0: throw new Error("Unsupported 'count' arg:" + count); michael@0: } michael@0: /* michael@0: function GetSundayInMonth(t, m, count){ michael@0: var year = YearFromTime(t); michael@0: var leap = InLeapYear(t); michael@0: var day = 0; michael@0: michael@0: if(m >= 1) day += DaysInMonth(0, leap); michael@0: if(m >= 2) day += DaysInMonth(1, leap); michael@0: if(m >= 3) day += DaysInMonth(2, leap); michael@0: if(m >= 4) day += DaysInMonth(3, leap); michael@0: if(m >= 5) day += DaysInMonth(4, leap); michael@0: if(m >= 6) day += DaysInMonth(5, leap); michael@0: if(m >= 7) day += DaysInMonth(6, leap); michael@0: if(m >= 8) day += DaysInMonth(7, leap); michael@0: if(m >= 9) day += DaysInMonth(8, leap); michael@0: if(m >= 10) day += DaysInMonth(9, leap); michael@0: if(m >= 11) day += DaysInMonth(10, leap); michael@0: michael@0: var month_start = TimeFromYear(year)+day*msPerDay; michael@0: var sunday = 0; michael@0: michael@0: if(count === "last"){ michael@0: for(var last_sunday = month_start+DaysInMonth(m, leap)*msPerDay; michael@0: WeekDay(last_sunday)>0; michael@0: last_sunday -= msPerDay michael@0: ){}; michael@0: sunday = last_sunday; michael@0: } michael@0: else { michael@0: for(var first_sunday = month_start; michael@0: WeekDay(first_sunday)>0; michael@0: first_sunday += msPerDay michael@0: ){}; michael@0: sunday = first_sunday+7*msPerDay*(count-1); michael@0: } michael@0: michael@0: return sunday; michael@0: }*/ michael@0: michael@0: function DaylightSavingTA(t) { michael@0: // t = t-LocalTZA; michael@0: michael@0: var DST_start = GetSundayInMonth(t, $DST_start_month, $DST_start_sunday) + michael@0: $DST_start_hour*msPerHour + michael@0: $DST_start_minutes*msPerMinute; michael@0: michael@0: var k = new Date(DST_start); michael@0: michael@0: var DST_end = GetSundayInMonth(t, $DST_end_month, $DST_end_sunday) + michael@0: $DST_end_hour*msPerHour + michael@0: $DST_end_minutes*msPerMinute; michael@0: michael@0: if ( t >= DST_start && t < DST_end ) { michael@0: return msPerHour; michael@0: } else { michael@0: return 0; michael@0: } michael@0: } michael@0: michael@0: //15.9.1.9 Local Time michael@0: function LocalTime(t){ michael@0: return t+LocalTZA+DaylightSavingTA(t); michael@0: } michael@0: michael@0: function UTC(t) { michael@0: return t-LocalTZA-DaylightSavingTA(t-LocalTZA); michael@0: } michael@0: michael@0: //15.9.1.10 Hours, Minutes, Second, and Milliseconds michael@0: function HourFromTime(t){ michael@0: return Math.floor(t/msPerHour)%HoursPerDay; michael@0: } michael@0: michael@0: function MinFromTime(t){ michael@0: return Math.floor(t/msPerMinute)%MinutesPerHour; michael@0: } michael@0: michael@0: function SecFromTime(t){ michael@0: return Math.floor(t/msPerSecond)%SecondsPerMinute; michael@0: } michael@0: michael@0: function msFromTime(t){ michael@0: return t%msPerSecond; michael@0: } michael@0: michael@0: //15.9.1.11 MakeTime (hour, min, sec, ms) michael@0: function MakeTime(hour, min, sec, ms){ michael@0: if ( !isFinite(hour) || !isFinite(min) || !isFinite(sec) || !isFinite(ms)) { michael@0: return Number.NaN; michael@0: } michael@0: michael@0: hour = ToInteger(hour); michael@0: min = ToInteger(min); michael@0: sec = ToInteger(sec); michael@0: ms = ToInteger(ms); michael@0: michael@0: return ((hour*msPerHour) + (min*msPerMinute) + (sec*msPerSecond) + ms); michael@0: } michael@0: michael@0: //15.9.1.12 MakeDay (year, month, date) michael@0: function MakeDay(year, month, date) { michael@0: if ( !isFinite(year) || !isFinite(month) || !isFinite(date)) { michael@0: return Number.NaN; michael@0: } michael@0: michael@0: year = ToInteger(year); michael@0: month = ToInteger(month); michael@0: date = ToInteger(date ); michael@0: michael@0: var result5 = year + Math.floor(month/12); michael@0: var result6 = month%12; michael@0: michael@0: var sign = ( year < 1970 ) ? -1 : 1; michael@0: var t = ( year < 1970 ) ? 1 : 0; michael@0: var y = ( year < 1970 ) ? 1969 : 1970; michael@0: michael@0: if( sign == -1 ){ michael@0: for ( y = 1969; y >= year; y += sign ) { michael@0: t += sign * DaysInYear(y)*msPerDay; michael@0: } michael@0: } else { michael@0: for ( y = 1970 ; y < year; y += sign ) { michael@0: t += sign * DaysInYear(y)*msPerDay; michael@0: } michael@0: } michael@0: michael@0: var leap = 0; michael@0: for ( var m = 0; m < month; m++ ) { michael@0: //if year is changed, than we need to recalculate leep michael@0: leap = InLeapYear(t); michael@0: t += DaysInMonth(m, leap)*msPerDay; michael@0: } michael@0: michael@0: if ( YearFromTime(t) != result5 ) { michael@0: return Number.NaN; michael@0: } michael@0: if ( MonthFromTime(t) != result6 ) { michael@0: return Number.NaN; michael@0: } michael@0: if ( DateFromTime(t) != 1 ) { michael@0: return Number.NaN; michael@0: } michael@0: michael@0: return Day(t)+date-1; michael@0: } michael@0: michael@0: //15.9.1.13 MakeDate (day, time) michael@0: function MakeDate( day, time ) { michael@0: if(!isFinite(day) || !isFinite(time)) { michael@0: return Number.NaN; michael@0: } michael@0: michael@0: return day*msPerDay+time; michael@0: } michael@0: michael@0: //15.9.1.14 TimeClip (time) michael@0: function TimeClip(time) { michael@0: if(!isFinite(time) || Math.abs(time) > 8.64e15){ michael@0: return Number.NaN; michael@0: } michael@0: michael@0: return ToInteger(time); michael@0: } michael@0: michael@0: //Test Functions michael@0: //ConstructDate is considered deprecated, and should not be used directly from michael@0: //test262 tests as it's incredibly sensitive to DST start/end dates that michael@0: //vary with geographic location. michael@0: function ConstructDate(year, month, date, hours, minutes, seconds, ms){ michael@0: /* michael@0: * 1. Call ToNumber(year) michael@0: * 2. Call ToNumber(month) michael@0: * 3. If date is supplied use ToNumber(date); else use 1 michael@0: * 4. If hours is supplied use ToNumber(hours); else use 0 michael@0: * 5. If minutes is supplied use ToNumber(minutes); else use 0 michael@0: * 6. If seconds is supplied use ToNumber(seconds); else use 0 michael@0: * 7. If ms is supplied use ToNumber(ms); else use 0 michael@0: * 8. If Result(1) is not NaN and 0 <= ToInteger(Result(1)) <= 99, Result(8) is michael@0: * 1900+ToInteger(Result(1)); otherwise, Result(8) is Result(1) michael@0: * 9. Compute MakeDay(Result(8), Result(2), Result(3)) michael@0: * 10. Compute MakeTime(Result(4), Result(5), Result(6), Result(7)) michael@0: * 11. Compute MakeDate(Result(9), Result(10)) michael@0: * 12. Set the [[Value]] property of the newly constructed object to TimeClip(UTC(Result(11))) michael@0: */ michael@0: var r1 = Number(year); michael@0: var r2 = Number(month); michael@0: var r3 = ((date && arguments.length > 2) ? Number(date) : 1); michael@0: var r4 = ((hours && arguments.length > 3) ? Number(hours) : 0); michael@0: var r5 = ((minutes && arguments.length > 4) ? Number(minutes) : 0); michael@0: var r6 = ((seconds && arguments.length > 5) ? Number(seconds) : 0); michael@0: var r7 = ((ms && arguments.length > 6) ? Number(ms) : 0); michael@0: michael@0: var r8 = r1; michael@0: michael@0: if(!isNaN(r1) && (0 <= ToInteger(r1)) && (ToInteger(r1) <= 99)) michael@0: r8 = 1900+r1; michael@0: michael@0: var r9 = MakeDay(r8, r2, r3); michael@0: var r10 = MakeTime(r4, r5, r6, r7); michael@0: var r11 = MakeDate(r9, r10); michael@0: michael@0: var retVal = TimeClip(UTC(r11)); michael@0: return retVal; michael@0: } michael@0: michael@0: michael@0: michael@0: /**** Python code for initialize the above constants michael@0: // We may want to replicate the following in JavaScript. michael@0: // However, using JS date operations to generate parameters that are then used to michael@0: // test those some date operations seems unsound. However, it isn't clear if there michael@0: //is a good interoperable alternative. michael@0: michael@0: # Copyright 2009 the Sputnik authors. All rights reserved. michael@0: # This code is governed by the BSD license found in the LICENSE file. michael@0: michael@0: def GetDaylightSavingsTimes(): michael@0: # Is the given floating-point time in DST? michael@0: def IsDst(t): michael@0: return time.localtime(t)[-1] michael@0: # Binary search to find an interval between the two times no greater than michael@0: # delta where DST switches, returning the midpoint. michael@0: def FindBetween(start, end, delta): michael@0: while end - start > delta: michael@0: middle = (end + start) / 2 michael@0: if IsDst(middle) == IsDst(start): michael@0: start = middle michael@0: else: michael@0: end = middle michael@0: return (start + end) / 2 michael@0: now = time.time() michael@0: one_month = (30 * 24 * 60 * 60) michael@0: # First find a date with different daylight savings. To avoid corner cases michael@0: # we try four months before and after today. michael@0: after = now + 4 * one_month michael@0: before = now - 4 * one_month michael@0: if IsDst(now) == IsDst(before) and IsDst(now) == IsDst(after): michael@0: logger.warning("Was unable to determine DST info.") michael@0: return None michael@0: # Determine when the change occurs between now and the date we just found michael@0: # in a different DST. michael@0: if IsDst(now) != IsDst(before): michael@0: first = FindBetween(before, now, 1) michael@0: else: michael@0: first = FindBetween(now, after, 1) michael@0: # Determine when the change occurs between three and nine months from the michael@0: # first. michael@0: second = FindBetween(first + 3 * one_month, first + 9 * one_month, 1) michael@0: # Find out which switch is into and which if out of DST michael@0: if IsDst(first - 1) and not IsDst(first + 1): michael@0: start = second michael@0: end = first michael@0: else: michael@0: start = first michael@0: end = second michael@0: return (start, end) michael@0: michael@0: michael@0: def GetDaylightSavingsAttribs(): michael@0: times = GetDaylightSavingsTimes() michael@0: if not times: michael@0: return None michael@0: (start, end) = times michael@0: def DstMonth(t): michael@0: return time.localtime(t)[1] - 1 michael@0: def DstHour(t): michael@0: return time.localtime(t - 1)[3] + 1 michael@0: def DstSunday(t): michael@0: if time.localtime(t)[2] > 15: michael@0: return "'last'" michael@0: else: michael@0: return "'first'" michael@0: def DstMinutes(t): michael@0: return (time.localtime(t - 1)[4] + 1) % 60 michael@0: attribs = { } michael@0: attribs['start_month'] = DstMonth(start) michael@0: attribs['end_month'] = DstMonth(end) michael@0: attribs['start_sunday'] = DstSunday(start) michael@0: attribs['end_sunday'] = DstSunday(end) michael@0: attribs['start_hour'] = DstHour(start) michael@0: attribs['end_hour'] = DstHour(end) michael@0: attribs['start_minutes'] = DstMinutes(start) michael@0: attribs['end_minutes'] = DstMinutes(end) michael@0: return attribs michael@0: michael@0: *********/ michael@0: michael@0: //--Test case registration----------------------------------------------------- michael@0: function runTestCase(testcase) { michael@0: if (testcase() !== true) { michael@0: $ERROR("Test case returned non-true value!"); michael@0: } michael@0: }