コード例 #1
0
ファイル: DateMath.cpp プロジェクト: youtube/h5vcc_hh
// Get the DST offset for the time passed in.
//
// NOTE: The implementation relies on the fact that no time zones have
// more than one daylight savings offset change per month.
// If this function is called with NaN it returns NaN.
static double getDSTOffset(ExecState* exec, double ms, double utcOffset)
{
    DSTOffsetCache& cache = exec->globalData().dstOffsetCache;
    double start = cache.start;
    double end = cache.end;

    if (start <= ms) {
        // If the time fits in the cached interval, return the cached offset.
        if (ms <= end) return cache.offset;

        // Compute a possible new interval end.
        double newEnd = end + cache.increment;

        if (ms <= newEnd) {
            double endOffset = calculateDSTOffset(newEnd, utcOffset);
            if (cache.offset == endOffset) {
                // If the offset at the end of the new interval still matches
                // the offset in the cache, we grow the cached time interval
                // and return the offset.
                cache.end = newEnd;
                cache.increment = msPerMonth;
                return endOffset;
            } else {
                double offset = calculateDSTOffset(ms, utcOffset);
                if (offset == endOffset) {
                    // The offset at the given time is equal to the offset at the
                    // new end of the interval, so that means that we've just skipped
                    // the point in time where the DST offset change occurred. Updated
                    // the interval to reflect this and reset the increment.
                    cache.start = ms;
                    cache.end = newEnd;
                    cache.increment = msPerMonth;
                } else {
                    // The interval contains a DST offset change and the given time is
                    // before it. Adjust the increment to avoid a linear search for
                    // the offset change point and change the end of the interval.
                    cache.increment /= 3;
                    cache.end = ms;
                }
                // Update the offset in the cache and return it.
                cache.offset = offset;
                return offset;
            }
        }
    }

    // Compute the DST offset for the time and shrink the cache interval
    // to only contain the time. This allows fast repeated DST offset
    // computations for the same time.
    double offset = calculateDSTOffset(ms, utcOffset);
    cache.offset = offset;
    cache.start = ms;
    cache.end = ms;
    cache.increment = msPerMonth;
    return offset;
}
コード例 #2
0
static int currentFullYear()
{
    double current = currentTimeMS();
    double utcOffset = calculateUTCOffset();
    double dstOffset = calculateDSTOffset(current, utcOffset);
    int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
    current += offset * msPerMinute;

    DateComponents date;
    date.setMillisecondsSinceEpochForMonth(current);
    return date.fullYear();
}
コード例 #3
0
int DateTimeYearFieldElement::defaultValueForStepDown() const
{
    double current = currentTimeMS();
    double utcOffset = calculateUTCOffset();
    double dstOffset = calculateDSTOffset(current, utcOffset);
    int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
    current += offset * msPerMinute;

    DateComponents date;
    date.setMillisecondsSinceEpochForMonth(current);
    return date.fullYear();
}
コード例 #4
0
Decimal MonthInputType::defaultValueForStepUp() const
{
    double current = currentTimeMS();
    double utcOffset = calculateUTCOffset();
    double dstOffset = calculateDSTOffset(current, utcOffset);
    int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
    current += offset * msPerMinute;

    DateComponents date;
    date.setMillisecondsSinceEpochForMonth(current);
    double months = date.monthsSinceEpoch();
    ASSERT(std::isfinite(months));
    return Decimal::fromDouble(months);
}
コード例 #5
0
ファイル: DateMath.cpp プロジェクト: youtube/h5vcc_hh
double parseDateFromNullTerminatedCharacters(const char* dateString)
{
    bool haveTZ;
    int offset;
    double ms = parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
    if (isnan(ms))
        return NaN;

    // fall back to local timezone
    if (!haveTZ) {
        double utcOffset = calculateUTCOffset();
        double dstOffset = calculateDSTOffset(ms, utcOffset);
        offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
    }
    return ms - (offset * msPerMinute);
}
double parseDateFromNullTerminatedCharacters(const char* dateString)
{
    bool haveTZ;
    int offset;
    double ms = parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
    if (std::isnan(ms))
        return std::numeric_limits<double>::quiet_NaN();

    // fall back to local timezone
    if (!haveTZ) {
        double utcOffset = calculateUTCOffset();
        double dstOffset = calculateDSTOffset(ms, utcOffset);
        offset = (utcOffset + dstOffset) / msPerMinute;
    }
    return ms - (offset * msPerMinute);
}
コード例 #7
0
ファイル: DateMath.cpp プロジェクト: gubaojian/trylearn
// Returns combined offset in millisecond (UTC + DST).
LocalTimeOffset calculateLocalTimeOffset(double ms, TimeType inputTimeType)
{
#if HAVE(TM_GMTOFF)
    double localToUTCTimeOffset = inputTimeType == LocalTime ? calculateUTCOffset() : 0;
#else
    double localToUTCTimeOffset = calculateUTCOffset();
#endif
    if (inputTimeType == LocalTime)
        ms -= localToUTCTimeOffset;

    // On Mac OS X, the call to localtime (see calculateDSTOffset) will return historically accurate
    // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript
    // standard explicitly dictates that historical information should not be considered when
    // determining DST. For this reason we shift away from years that localtime can handle but would
    // return historically accurate information.
    int year = msToYear(ms);
    int equivalentYear = equivalentYearForDST(year);
    if (year != equivalentYear) {
        bool leapYear = isLeapYear(year);
        int dayInYearLocal = dayInYear(ms, year);
        int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear);
        int month = monthFromDayInYear(dayInYearLocal, leapYear);
        double day = dateToDaysFrom1970(equivalentYear, month, dayInMonth);
        ms = (day * msPerDay) + msToMilliseconds(ms);
    }

    double localTimeSeconds = ms / msPerSecond;
    if (localTimeSeconds > maxUnixTime)
        localTimeSeconds = maxUnixTime;
    else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0).
        localTimeSeconds += secondsPerDay;
    // FIXME: time_t has a potential problem in 2038.
    time_t localTime = static_cast<time_t>(localTimeSeconds);

#if HAVE(TM_GMTOFF)
    tm localTM;
    getLocalTime(&localTime, &localTM);
    return LocalTimeOffset(localTM.tm_isdst, localTM.tm_gmtoff * msPerSecond);
#else
    double dstOffset = calculateDSTOffset(localTime, localToUTCTimeOffset);
    return LocalTimeOffset(dstOffset, localToUTCTimeOffset + dstOffset);
#endif
}