⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datemath.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        result -= getDSTOffset(result, utcOffset);    }    return result;}void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm){    // input is UTC    double dstOff = 0.0;    const double utcOff = getUTCOffset();    if (!outputIsUTC) {  // convert to local time        dstOff = getDSTOffset(ms, utcOff);        ms += dstOff + utcOff;    }    const int year = msToYear(ms);    tm.second   =  msToSeconds(ms);    tm.minute   =  msToMinutes(ms);    tm.hour     =  msToHours(ms);    tm.weekDay  =  msToWeekDay(ms);    tm.yearDay  =  dayInYear(ms, year);    tm.monthDay =  dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year));    tm.month    =  monthFromDayInYear(tm.yearDay, isLeapYear(year));    tm.year     =  year - 1900;    tm.isDST    =  dstOff != 0.0;    tm.utcOffset = static_cast<long>((dstOff + utcOff) / msPerSecond);    tm.timeZone = NULL;}void initDateMath(){#ifndef NDEBUG    static bool alreadyInitialized;    ASSERT(!alreadyInitialized++);#endif    equivalentYearForDST(2000); // Need to call once to initialize a static used in this function.#if PLATFORM(DARWIN)    // Register for a notification whenever the time zone changes.    uint32_t status = notify_register_check("com.apple.system.timezone", &s_notificationToken);    if (status == NOTIFY_STATUS_OK) {        s_cachedUTCOffset = calculateUTCOffset();        s_haveCachedUTCOffset = true;    }#endif}static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, int second){    double days = (day - 32075)        + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4)        + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12        - floor(3 * ((year + 4900.0 + (mon - 14) / 12) / 100) / 4)        - 2440588;    return ((days * hoursPerDay + hour) * minutesPerHour + minute) * secondsPerMinute + second;}// We follow the recommendation of RFC 2822 to consider all// obsolete time zones not listed here equivalent to "-0000".static const struct KnownZone {#if !PLATFORM(WIN_OS)    const#endif        char tzName[4];    int tzOffset;} known_zones[] = {    { "UT", 0 },    { "GMT", 0 },    { "EST", -300 },    { "EDT", -240 },    { "CST", -360 },    { "CDT", -300 },    { "MST", -420 },    { "MDT", -360 },    { "PST", -480 },    { "PDT", -420 }};inline static void skipSpacesAndComments(const char*& s){    int nesting = 0;    char ch;    while ((ch = *s)) {        if (!isASCIISpace(ch)) {            if (ch == '(')                nesting++;            else if (ch == ')' && nesting > 0)                nesting--;            else if (nesting == 0)                break;        }        s++;    }}// returns 0-11 (Jan-Dec); -1 on failurestatic int findMonth(const char* monthStr){    ASSERT(monthStr);    char needle[4];    for (int i = 0; i < 3; ++i) {        if (!*monthStr)            return -1;        needle[i] = static_cast<char>(toASCIILower(*monthStr++));    }    needle[3] = '\0';    const char *haystack = "janfebmaraprmayjunjulaugsepoctnovdec";    const char *str = strstr(haystack, needle);    if (str) {        int position = static_cast<int>(str - haystack);        if (position % 3 == 0)            return position / 3;    }    return -1;}static bool parseLong(const char* string, char** stopPosition, int base, long* result){    *result = strtol(string, stopPosition, base);    // Avoid the use of errno as it is not available on Windows CE    if (string == *stopPosition || *result == LONG_MIN || *result == LONG_MAX)        return false;    return true;}double parseDate(const UString &date){    // This parses a date in the form:    //     Tuesday, 09-Nov-99 23:12:40 GMT    // or    //     Sat, 01-Jan-2000 08:00:00 GMT    // or    //     Sat, 01 Jan 2000 08:00:00 GMT    // or    //     01 Jan 99 22:00 +0100    (exceptions in rfc822/rfc2822)    // ### non RFC formats, added for Javascript:    //     [Wednesday] January 09 1999 23:12:40 GMT    //     [Wednesday] January 09 23:12:40 GMT 1999    //    // We ignore the weekday.    CString dateCString = date.UTF8String();    const char *dateString = dateCString.c_str();         // Skip leading space    skipSpacesAndComments(dateString);    long month = -1;    const char *wordStart = dateString;    // Check contents of first words if not number    while (*dateString && !isASCIIDigit(*dateString)) {        if (isASCIISpace(*dateString) || *dateString == '(') {            if (dateString - wordStart >= 3)                month = findMonth(wordStart);            skipSpacesAndComments(dateString);            wordStart = dateString;        } else           dateString++;    }    // Missing delimiter between month and day (like "January29")?    if (month == -1 && wordStart != dateString)        month = findMonth(wordStart);    skipSpacesAndComments(dateString);    if (!*dateString)        return NaN;    // ' 09-Nov-99 23:12:40 GMT'    char* newPosStr;    long day;    if (!parseLong(dateString, &newPosStr, 10, &day))        return NaN;    dateString = newPosStr;    if (!*dateString)        return NaN;    if (day < 0)        return NaN;    long year = 0;    if (day > 31) {        // ### where is the boundary and what happens below?        if (*dateString != '/')            return NaN;        // looks like a YYYY/MM/DD date        if (!*++dateString)            return NaN;        year = day;        if (!parseLong(dateString, &newPosStr, 10, &month))            return NaN;        month -= 1;        dateString = newPosStr;        if (*dateString++ != '/' || !*dateString)            return NaN;        if (!parseLong(dateString, &newPosStr, 10, &day))            return NaN;        dateString = newPosStr;    } else if (*dateString == '/' && month == -1) {        dateString++;        // This looks like a MM/DD/YYYY date, not an RFC date.        month = day - 1; // 0-based        if (!parseLong(dateString, &newPosStr, 10, &day))            return NaN;        if (day < 1 || day > 31)            return NaN;        dateString = newPosStr;        if (*dateString == '/')            dateString++;        if (!*dateString)            return NaN;     } else {        if (*dateString == '-')            dateString++;        skipSpacesAndComments(dateString);        if (*dateString == ',')            dateString++;        if (month == -1) { // not found yet            month = findMonth(dateString);            if (month == -1)                return NaN;            while (*dateString && *dateString != '-' && *dateString != ',' && !isASCIISpace(*dateString))                dateString++;            if (!*dateString)                return NaN;            // '-99 23:12:40 GMT'            if (*dateString != '-' && *dateString != '/' && *dateString != ',' && !isASCIISpace(*dateString))                return NaN;            dateString++;        }    }    if (month < 0 || month > 11)        return NaN;    // '99 23:12:40 GMT'    if (year <= 0 && *dateString) {        if (!parseLong(dateString, &newPosStr, 10, &year))            return NaN;    }        // Don't fail if the time is missing.    long hour = 0;    long minute = 0;    long second = 0;    if (!*newPosStr)        dateString = newPosStr;    else {        // ' 23:12:40 GMT'        if (!(isASCIISpace(*newPosStr) || *newPosStr == ',')) {            if (*newPosStr != ':')                return NaN;            // There was no year; the number was the hour.            year = -1;        } else {            // in the normal case (we parsed the year), advance to the next number            dateString = ++newPosStr;            skipSpacesAndComments(dateString);        }        parseLong(dateString, &newPosStr, 10, &hour);        // Do not check for errno here since we want to continue        // even if errno was set becasue we are still looking        // for the timezone!        // Read a number? If not, this might be a timezone name.        if (newPosStr != dateString) {            dateString = newPosStr;            if (hour < 0 || hour > 23)                return NaN;            if (!*dateString)                return NaN;            // ':12:40 GMT'            if (*dateString++ != ':')                return NaN;            if (!parseLong(dateString, &newPosStr, 10, &minute))                return NaN;            dateString = newPosStr;            if (minute < 0 || minute > 59)                return NaN;            // ':40 GMT'            if (*dateString && *dateString != ':' && !isASCIISpace(*dateString))                return NaN;            // seconds are optional in rfc822 + rfc2822            if (*dateString ==':') {                dateString++;                if (!parseLong(dateString, &newPosStr, 10, &second))                    return NaN;                dateString = newPosStr;                            if (second < 0 || second > 59)                    return NaN;            }            skipSpacesAndComments(dateString);            if (strncasecmp(dateString, "AM", 2) == 0) {                if (hour > 12)                    return NaN;                if (hour == 12)                    hour = 0;                dateString += 2;                skipSpacesAndComments(dateString);            } else if (strncasecmp(dateString, "PM", 2) == 0) {                if (hour > 12)                    return NaN;                if (hour != 12)                    hour += 12;                dateString += 2;                skipSpacesAndComments(dateString);            }        }    }    bool haveTZ = false;    int offset = 0;    // Don't fail if the time zone is missing.     // Some websites omit the time zone (4275206).    if (*dateString) {        if (strncasecmp(dateString, "GMT", 3) == 0 || strncasecmp(dateString, "UTC", 3) == 0) {            dateString += 3;            haveTZ = true;        }        if (*dateString == '+' || *dateString == '-') {            long o;            if (!parseLong(dateString, &newPosStr, 10, &o))                return NaN;            dateString = newPosStr;            if (o < -9959 || o > 9959)                return NaN;            int sgn = (o < 0) ? -1 : 1;            o = abs(o);            if (*dateString != ':') {                offset = ((o / 100) * 60 + (o % 100)) * sgn;            } else { // GMT+05:00                long o2;                if (!parseLong(dateString, &newPosStr, 10, &o2))                    return NaN;                dateString = newPosStr;                offset = (o * 60 + o2) * sgn;            }            haveTZ = true;        } else {            for (int i = 0; i < int(sizeof(known_zones) / sizeof(KnownZone)); i++) {                if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) {                    offset = known_zones[i].tzOffset;                    dateString += strlen(known_zones[i].tzName);                    haveTZ = true;                    break;                }            }        }    }    skipSpacesAndComments(dateString);    if (*dateString && year == -1) {        if (!parseLong(dateString, &newPosStr, 10, &year))            return NaN;        dateString = newPosStr;    }         skipSpacesAndComments(dateString);         // Trailing garbage    if (*dateString)        return NaN;    // Y2K: Handle 2 digit years.    if (year >= 0 && year < 100) {        if (year < 50)            year += 2000;        else            year += 1900;    }    // fall back to local timezone    if (!haveTZ) {        GregorianDateTime t;        t.monthDay = day;        t.month = month;        t.year = year - 1900;        t.isDST = -1;        t.second = second;        t.minute = minute;        t.hour = hour;        // Use our gregorianDateTimeToMS() rather than mktime() as the latter can't handle the full year range.        return gregorianDateTimeToMS(t, 0, false);    }    return (ymdhmsToSeconds(year, month + 1, day, hour, minute, second) - (offset * 60.0)) * msPerSecond;}double timeClip(double t){    if (!isfinite(t))        return NaN;    if (fabs(t) > 8.64E15)        return NaN;    return trunc(t);}UString formatDate(const GregorianDateTime &t){    char buffer[100];    snprintf(buffer, sizeof(buffer), "%s %s %02d %04d",        weekdayName[(t.weekDay + 6) % 7],        monthName[t.month], t.monthDay, t.year + 1900);    return buffer;}UString formatDateUTCVariant(const GregorianDateTime &t){    char buffer[100];    snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d",        weekdayName[(t.weekDay + 6) % 7],        t.monthDay, monthName[t.month], t.year + 1900);    return buffer;}UString formatTime(const GregorianDateTime &t, bool utc){    char buffer[100];    if (utc) {        snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);    } else {        int offset = abs(gmtoffset(t));        char tzname[70];        struct tm gtm = t;        strftime(tzname, sizeof(tzname), "%Z", &gtm);        if (tzname[0]) {            snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",                t.hour, t.minute, t.second,                gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, tzname);        } else {            snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",                t.hour, t.minute, t.second,                gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);        }    }    return UString(buffer);}} // namespace JSC

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -