Bug 834988 - Clarify that all the DST-offset methods take a time in UTC seconds, and that the internal fields store UTC values. Also add documentation comments by the related methods. r=dmandelin

--HG--
extra : rebase_source : ee848c192ddafe87cdb8388f0d2b81a0d5e4be9a
This commit is contained in:
Jeff Walden 2013-01-25 16:50:24 -08:00
parent c6b1acb9c6
commit 9f1d235f1e
3 changed files with 47 additions and 39 deletions

View File

@ -397,8 +397,8 @@ DaylightSavingTA(double t, DateTimeInfo *dtInfo)
t = MakeDate(day, TimeWithinDay(t));
}
int64_t timeMilliseconds = static_cast<int64_t>(t);
int64_t offsetMilliseconds = dtInfo->getDSTOffsetMilliseconds(timeMilliseconds);
int64_t utcMilliseconds = static_cast<int64_t>(t);
int64_t offsetMilliseconds = dtInfo->getDSTOffsetMilliseconds(utcMilliseconds);
return static_cast<double>(offsetMilliseconds);
}

View File

@ -161,10 +161,10 @@ js::DateTimeInfo::DateTimeInfo()
}
int64_t
js::DateTimeInfo::computeDSTOffsetMilliseconds(int64_t localTimeSeconds)
js::DateTimeInfo::computeDSTOffsetMilliseconds(int64_t utcSeconds)
{
MOZ_ASSERT(localTimeSeconds >= 0);
MOZ_ASSERT(localTimeSeconds <= MaxUnixTimeT);
MOZ_ASSERT(utcSeconds >= 0);
MOZ_ASSERT(utcSeconds <= MaxUnixTimeT);
#if defined(XP_WIN)
// Windows does not follow POSIX. Updates to the TZ environment variable
@ -174,12 +174,10 @@ js::DateTimeInfo::computeDSTOffsetMilliseconds(int64_t localTimeSeconds)
#endif
struct tm tm;
if (!ComputeLocalTime(static_cast<time_t>(localTimeSeconds), &tm))
if (!ComputeLocalTime(static_cast<time_t>(utcSeconds), &tm))
return 0;
int32_t utcToLocalOffsetSeconds = UTCToLocalStandardOffsetSeconds();
int32_t dayoff = int32_t((localTimeSeconds + utcToLocalOffsetSeconds) % SecondsPerDay);
int32_t dayoff = int32_t((utcSeconds + UTCToLocalStandardOffsetSeconds()) % SecondsPerDay);
int32_t tmoff = tm.tm_sec + (tm.tm_min * SecondsPerMinute) + (tm.tm_hour * SecondsPerHour);
int32_t diff = tmoff - dayoff;
@ -191,17 +189,17 @@ js::DateTimeInfo::computeDSTOffsetMilliseconds(int64_t localTimeSeconds)
}
int64_t
js::DateTimeInfo::getDSTOffsetMilliseconds(int64_t localTimeMilliseconds)
js::DateTimeInfo::getDSTOffsetMilliseconds(int64_t utcMilliseconds)
{
sanityCheck();
int64_t localTimeSeconds = localTimeMilliseconds / msPerSecond;
int64_t utcSeconds = utcMilliseconds / msPerSecond;
if (localTimeSeconds > MaxUnixTimeT) {
localTimeSeconds = MaxUnixTimeT;
} else if (localTimeSeconds < 0) {
if (utcSeconds > MaxUnixTimeT) {
utcSeconds = MaxUnixTimeT;
} else if (utcSeconds < 0) {
/* Go ahead a day to make localtime work (does not work with 0). */
localTimeSeconds = SecondsPerDay;
utcSeconds = SecondsPerDay;
}
/*
@ -210,64 +208,60 @@ js::DateTimeInfo::getDSTOffsetMilliseconds(int64_t localTimeMilliseconds)
* values, must result in a cache miss.
*/
if (rangeStartSeconds <= localTimeSeconds &&
localTimeSeconds <= rangeEndSeconds) {
if (rangeStartSeconds <= utcSeconds && utcSeconds <= rangeEndSeconds)
return offsetMilliseconds;
}
if (oldRangeStartSeconds <= localTimeSeconds &&
localTimeSeconds <= oldRangeEndSeconds) {
if (oldRangeStartSeconds <= utcSeconds && utcSeconds <= oldRangeEndSeconds)
return oldOffsetMilliseconds;
}
oldOffsetMilliseconds = offsetMilliseconds;
oldRangeStartSeconds = rangeStartSeconds;
oldRangeEndSeconds = rangeEndSeconds;
if (rangeStartSeconds <= localTimeSeconds) {
if (rangeStartSeconds <= utcSeconds) {
int64_t newEndSeconds = Min(rangeEndSeconds + RangeExpansionAmount, MaxUnixTimeT);
if (newEndSeconds >= localTimeSeconds) {
if (newEndSeconds >= utcSeconds) {
int64_t endOffsetMilliseconds = computeDSTOffsetMilliseconds(newEndSeconds);
if (endOffsetMilliseconds == offsetMilliseconds) {
rangeEndSeconds = newEndSeconds;
return offsetMilliseconds;
}
offsetMilliseconds = computeDSTOffsetMilliseconds(localTimeSeconds);
offsetMilliseconds = computeDSTOffsetMilliseconds(utcSeconds);
if (offsetMilliseconds == endOffsetMilliseconds) {
rangeStartSeconds = localTimeSeconds;
rangeStartSeconds = utcSeconds;
rangeEndSeconds = newEndSeconds;
} else {
rangeEndSeconds = localTimeSeconds;
rangeEndSeconds = utcSeconds;
}
return offsetMilliseconds;
}
offsetMilliseconds = computeDSTOffsetMilliseconds(localTimeSeconds);
rangeStartSeconds = rangeEndSeconds = localTimeSeconds;
offsetMilliseconds = computeDSTOffsetMilliseconds(utcSeconds);
rangeStartSeconds = rangeEndSeconds = utcSeconds;
return offsetMilliseconds;
}
int64_t newStartSeconds = Max<int64_t>(rangeStartSeconds - RangeExpansionAmount, 0);
if (newStartSeconds <= localTimeSeconds) {
if (newStartSeconds <= utcSeconds) {
int64_t startOffsetMilliseconds = computeDSTOffsetMilliseconds(newStartSeconds);
if (startOffsetMilliseconds == offsetMilliseconds) {
rangeStartSeconds = newStartSeconds;
return offsetMilliseconds;
}
offsetMilliseconds = computeDSTOffsetMilliseconds(localTimeSeconds);
offsetMilliseconds = computeDSTOffsetMilliseconds(utcSeconds);
if (offsetMilliseconds == startOffsetMilliseconds) {
rangeStartSeconds = newStartSeconds;
rangeEndSeconds = localTimeSeconds;
rangeEndSeconds = utcSeconds;
} else {
rangeStartSeconds = localTimeSeconds;
rangeStartSeconds = utcSeconds;
}
return offsetMilliseconds;
}
rangeStartSeconds = rangeEndSeconds = localTimeSeconds;
offsetMilliseconds = computeDSTOffsetMilliseconds(localTimeSeconds);
rangeStartSeconds = rangeEndSeconds = utcSeconds;
offsetMilliseconds = computeDSTOffsetMilliseconds(utcSeconds);
return offsetMilliseconds;
}

View File

@ -98,15 +98,21 @@ class DateTimeInfo
{
public:
DateTimeInfo();
int64_t getDSTOffsetMilliseconds(int64_t localTimeMilliseconds);
/*
* Get the DST offset in milliseconds at a UTC time. This is usually
* either 0 or |msPerSecond * SecondsPerHour|, but at least one exotic time
* zone (Lord Howe Island, Australia) has a fractional-hour offset, just to
* keep things interesting.
*/
int64_t getDSTOffsetMilliseconds(int64_t utcMilliseconds);
void updateTimeZoneAdjustment();
/* ES5 15.9.1.7. */
double localTZA() { return localTZA_; }
private:
int64_t computeDSTOffsetMilliseconds(int64_t localTimeSeconds);
/*
* The current local time zone adjustment, cached because retrieving this
* dynamically is Slow, and a certain venerable benchmark which shall not
@ -119,11 +125,19 @@ class DateTimeInfo
*/
double localTZA_;
/*
* Compute the DST offset at the given UTC time in seconds from the epoch.
* (getDSTOffsetMilliseconds attempts to return a cached value, but in case
* of a cache miss it calls this method. The cache is represented through
* the offset* and *{Start,End}Seconds fields below.)
*/
int64_t computeDSTOffsetMilliseconds(int64_t utcSeconds);
int64_t offsetMilliseconds;
int64_t rangeStartSeconds, rangeEndSeconds;
int64_t rangeStartSeconds, rangeEndSeconds; // UTC-based
int64_t oldOffsetMilliseconds;
int64_t oldRangeStartSeconds, oldRangeEndSeconds;
int64_t oldRangeStartSeconds, oldRangeEndSeconds; // UTC-based
static const int64_t MaxUnixTimeT = 2145859200; /* time_t 12/31/2037 */