Bug 836404 - Provide better timezone support in jstests. r=jwalden

--HG--
extra : rebase_source : 11267ba920def4077e843230cddb583cbe8bad6d
This commit is contained in:
André Bargull 2013-04-03 12:20:02 -07:00
parent 031f0b5189
commit e6c4ed4769

View File

@ -8,6 +8,7 @@
* Date functions used by tests in Date suite
*
*/
var msPerYear = 31536000000;
var msPerDay = 86400000;
var HoursPerDay = 24;
var MinutesPerHour = 60;
@ -15,11 +16,19 @@ var SecondsPerMinute = 60;
var msPerSecond = 1000;
var msPerMinute = 60000; // msPerSecond * SecondsPerMinute
var msPerHour = 3600000; // msPerMinute * MinutesPerHour
var TZ_DIFF = getTimeZoneDiff(); // offset of tester's timezone from UTC
var TZ_ADJUST = TZ_DIFF * msPerHour;
var TZ_PST = -8; // offset of Pacific Standard Time from UTC
var TZ_DIFF_RAW = GetRawTimezoneOffset(); // raw offset of tester's timezone from UTC
var TZ_DIFF = GetTimezoneOffset(); // offset of tester's timezone from UTC
var PST_DIFF_RAW = TZ_DIFF_RAW - TZ_PST; // raw offset of tester's timezone from PST
var PST_DIFF = TZ_DIFF - TZ_PST; // offset of tester's timezone from PST
var TZ_ADJUST = TZ_DIFF_RAW * msPerHour;
var PST_ADJUST = TZ_PST * msPerHour;
var DST_PERIOD = DaylightSavingPeriod(); // time period when DST is used
var DST_1970 = DaylightSavingObserved(1970); // Was DST observed in 1970?
var DST_1971 = DaylightSavingObserved(1971); // Was DST observed in 1971?
var TIME_0000 = (function ()
{ // calculate time for year 0
for ( var time = 0, year = 1969; year >= 0; year-- ) {
@ -43,9 +52,71 @@ var TIME_NOW = now.valueOf(); //valueOf() is to accurate to the millisecond
* We calculate the proper number dynamically for any tester. We just
* have to be careful not to use a date subject to Daylight Savings Time...
*/
function getTimeZoneDiff()
function GetRawTimezoneOffset()
{
return -((new Date(2000, 1, 1)).getTimezoneOffset())/60;
var t1 = new Date(2000, 1, 1).getTimezoneOffset();
var t2 = new Date(2000, 1 + 6, 1).getTimezoneOffset();
if ((t1 - t2) >= 0) {
// 1) timezone without daylight saving time
// 2) northern hemisphere with daylight saving time
return -t1 / MinutesPerHour;
} else {
// 3) southern hemisphere with daylight saving time
return -t2 / MinutesPerHour;
}
}
/*
* Returns the timezone offset, possibly including daylight saving time.
* (This function is only used to obtain the relative timezone offset to PST,
* see TZ_DIFF and PST_DIFF in adjustResultArray().)
*/
function GetTimezoneOffset()
{
return -(new Date(2000, 1, 1).getTimezoneOffset()) / MinutesPerHour;
}
/*
* Determine when daylight saving time is used in the current timezone.
*/
function DaylightSavingPeriod()
{
var t1 = new Date(2000, 1, 1).getTimezoneOffset();
var t2 = new Date(2000, 1 + 6, 1).getTimezoneOffset();
if (t1 == t2) {
// timezone without daylight saving time
return 0;
} else if ((t1 - t2) > 0) {
// northern hemisphere with daylight saving time
return 1;
} else {
// southern hemisphere with daylight saving time
return -1;
}
}
/*
* Test whether daylight time saving was observed in the supplied year
*/
function DaylightSavingObserved(y)
{
var t1 = new Date(y, 1, 1).getTimezoneOffset();
var t2 = new Date(y, 1 + 6, 1).getTimezoneOffset();
return (t1 != t2);
}
/*
* Don't apply DST near start of epoch unless absolutely necessary
*/
function IgnoreDaylightSaving(t)
{
if ((0 <= t && t < msPerYear) && !DST_1970) {
return true;
}
if ((msPerYear <= t && t < 2*msPerYear) && !DST_1971) {
return true;
}
return false;
}
/*
@ -74,14 +145,18 @@ function adjustResultArray(ResultArray, msMode)
{
// The hard-coded UTC milliseconds from Time 0 derives from a UTC date.
// Shift to the right by the offset between UTC and the tester.
var t = ResultArray[TIME] + TZ_DIFF*msPerHour;
if (IgnoreDaylightSaving(ResultArray[TIME])) {
var t = ResultArray[TIME] + TZ_DIFF_RAW*msPerHour;
} else {
var t = ResultArray[TIME] + TZ_DIFF*msPerHour;
}
// Use our date arithmetic functions to determine the local hour, day, etc.
ResultArray[HOURS] = HourFromTime(t);
ResultArray[DAY] = WeekDay(t);
ResultArray[DATE] = DateFromTime(t);
ResultArray[MONTH] = MonthFromTime(t);
ResultArray[YEAR] = YearFromTime(t);
ResultArray[YEAR] = YearFromTime(t);
}
else
{
@ -295,7 +370,7 @@ function msFromTime( t ) {
return ( (ms < 0 ) ? msPerSecond + ms : ms );
}
function LocalTZA() {
return ( TZ_DIFF * msPerHour );
return ( TZ_DIFF_RAW * msPerHour );
}
function UTC( t ) {
return ( t - LocalTZA() - DaylightSavingTA(t - LocalTZA()) );
@ -304,13 +379,27 @@ function LocalTime( t ) {
return ( t + LocalTZA() + DaylightSavingTA(t) );
}
function DaylightSavingTA( t ) {
t = t - LocalTZA();
if (IgnoreDaylightSaving(t)) {
return 0;
}
var dst_start = GetDSTStart(t);
var dst_end = GetDSTEnd(t);
if (DST_PERIOD > 0) {
// northern hemisphere
var dst_start = GetDSTStart(t);
var dst_end = GetDSTEnd(t);
if ( t >= dst_start && t < dst_end )
return msPerHour;
if ( t >= dst_start && t < dst_end )
return msPerHour;
} else if (DST_PERIOD < 0) {
// southern hemisphere
var dst_start = GetDSTStart_Southern(t);
var dst_end = GetDSTEnd_Southern(t);
if ( t >= dst_start && t < GetDSTEnd_Southern(t + msPerYear) )
return msPerHour;
if ( t < dst_end && t >= GetDSTEnd_Southern(t - msPerYear) )
return msPerHour;
}
return 0;
}
@ -416,6 +505,21 @@ function GetOldDSTEnd( t )
return (GetLastSundayInMonth(t, 9) + 2*msPerHour - LocalTZA());
}
/*
* Daylight saving time start/end date for 'Australia'
* (arbitrarily chosen as a representative for the southern hemisphere)
*/
function GetDSTStart_Southern( t )
{
return (GetFirstSundayInMonth(t, 9) + 2*msPerHour - LocalTZA());
}
function GetDSTEnd_Southern( t )
{
return (GetFirstSundayInMonth(t, 3) + 2*msPerHour - LocalTZA());
}
function MakeTime( hour, min, sec, ms ) {
if ( isNaN( hour ) || isNaN( min ) || isNaN( sec ) || isNaN( ms ) ) {
return Number.NaN;