/*
 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
 * Copyright (C) 2006-2019 Apple Inc. All rights reserved.
 * Copyright (C) 2009 Google Inc. All rights reserved.
 * Copyright (C) 2007-2009 Torch Mobile, Inc.
 * Copyright (C) 2010 &yet, LLC. (nate@andyet.net)
 *
 * The Original Code is Mozilla Communicator client code, released
 * March 31, 1998.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998
 * the Initial Developer. All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Alternatively, the contents of this file may be used under the terms
 * of either the Mozilla Public License Version 1.1, found at
 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
 * (the "GPL"), in which case the provisions of the MPL or the GPL are
 * applicable instead of those above.  If you wish to allow use of your
 * version of this file only under the terms of one of those two
 * licenses (the MPL or the GPL) and not to allow others to use your
 * version of this file under the LGPL, indicate your decision by
 * deletingthe provisions above and replace them with the notice and
 * other provisions required by the MPL or the GPL, as the case may be.
 * If you do not delete the provisions above, a recipient may use your
 * version of this file under any of the LGPL, the MPL or the GPL.

 * Copyright 2006-2008 the V8 project authors. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of Google Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include <wtf/DateMath.h>

#include <algorithm>
#include <limits>
#include <stdint.h>
#include <time.h>
#include <unicode/ucal.h>
#include <wtf/Assertions.h>
#include <wtf/ASCIICType.h>
#include <wtf/Language.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/ThreadSpecific.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/unicode/UTF8Conversion.h>
#include <wtf/unicode/icu/ICUHelpers.h>

#if OS(WINDOWS)
#include <windows.h>
#endif

namespace WTF {

// FIXME: Should this function go into StringCommon.h or some other header?
template<unsigned length> inline bool startsWithLettersIgnoringASCIICase(const char* string, const char (&lowercaseLetters)[length])
{
    return equalLettersIgnoringASCIICase(string, lowercaseLetters, length - 1);
}

static Lock innerTimeZoneOverrideLock;
static Vector<UChar>& innerTimeZoneOverride() WTF_REQUIRES_LOCK(innerTimeZoneOverrideLock)
{
    static NeverDestroyed<Vector<UChar>> timeZoneOverride;
    return timeZoneOverride;
}

/* Constants */

const ASCIILiteral weekdayName[7] = { "Mon"_s, "Tue"_s, "Wed"_s, "Thu"_s, "Fri"_s, "Sat"_s, "Sun"_s };
const ASCIILiteral monthName[12] = { "Jan"_s, "Feb"_s, "Mar"_s, "Apr"_s, "May"_s, "Jun"_s, "Jul"_s, "Aug"_s, "Sep"_s, "Oct"_s, "Nov"_s, "Dec"_s };
const ASCIILiteral monthFullName[12] = { "January"_s, "February"_s, "March"_s, "April"_s, "May"_s, "June"_s, "July"_s, "August"_s, "September"_s, "October"_s, "November"_s, "December"_s };

// Day of year for the first day of each month, where index 0 is January, and day 0 is January 1.
// First for non-leap years, then for leap years.
const int firstDayOfMonth[2][12] = {
    {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
    {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
};

#if !OS(WINDOWS) || HAVE(TM_GMTOFF)
static inline void getLocalTime(const time_t* localTime, struct tm* localTM)
{
#if HAVE(LOCALTIME_R)
    localtime_r(localTime, localTM);
#else
    localtime_s(localTime, localTM);
#endif
}
#endif

static void appendTwoDigitNumber(StringBuilder& builder, int number)
{
    ASSERT(number >= 0);
    ASSERT(number < 100);
    builder.append(static_cast<LChar>('0' + number / 10));
    builder.append(static_cast<LChar>('0' + number % 10));
}

static inline double msToMilliseconds(double ms)
{
    double result = fmod(ms, msPerDay);
    if (result < 0)
        result += msPerDay;
    return result;
}

// There is a hard limit at 2038 that we currently do not have a workaround
// for (rdar://problem/5052975).
static inline int maximumYearForDST()
{
    return 2037;
}

static inline int minimumYearForDST()
{
    // Because of the 2038 issue (see maximumYearForDST) if the current year is
    // greater than the max year minus 27 (2010), we want to use the max year
    // minus 27 instead, to ensure there is a range of 28 years that all years
    // can map to.
    return std::min(msToYear(jsCurrentTime()), maximumYearForDST() - 27) ;
}

/*
 * Find an equivalent year for the one given, where equivalence is deterined by
 * the two years having the same leapness and the first day of the year, falling
 * on the same day of the week.
 *
 * This function returns a year between this current year and 2037, however this
 * function will potentially return incorrect results if the current year is after
 * 2010, (rdar://problem/5052975), if the year passed in is before 1900 or after
 * 2100, (rdar://problem/5055038).
 */
int equivalentYearForDST(int year)
{
    // It is ok if the cached year is not the current year as long as the rules
    // for DST did not change between the two years; if they did the app would need
    // to be restarted.
    static int minYear = minimumYearForDST();
    int maxYear = maximumYearForDST();

    int difference;
    if (year > maxYear)
        difference = minYear - year;
    else if (year < minYear)
        difference = maxYear - year;
    else
        return year;

    int quotient = difference / 28;
    int product = (quotient) * 28;

    year += product;
    return year;
}

#if OS(WINDOWS)
typedef BOOL(WINAPI* callGetTimeZoneInformationForYear_t)(USHORT, PDYNAMIC_TIME_ZONE_INFORMATION, LPTIME_ZONE_INFORMATION);

static callGetTimeZoneInformationForYear_t timeZoneInformationForYearFunction()
{
    static callGetTimeZoneInformationForYear_t getTimeZoneInformationForYear = nullptr;

    if (getTimeZoneInformationForYear)
        return getTimeZoneInformationForYear;

    HMODULE module = ::GetModuleHandleW(L"kernel32.dll");
    if (!module)
        return nullptr;

    getTimeZoneInformationForYear = reinterpret_cast<callGetTimeZoneInformationForYear_t>(::GetProcAddress(module, "GetTimeZoneInformationForYear"));

    return getTimeZoneInformationForYear;
}
#endif

static int32_t calculateUTCOffset()
{
#if OS(WINDOWS)
    TIME_ZONE_INFORMATION timeZoneInformation;
    DWORD rc = 0;

    if (callGetTimeZoneInformationForYear_t timeZoneFunction = timeZoneInformationForYearFunction()) {
        // If available, use the Windows API call that takes into account the varying DST from
        // year to year.
        SYSTEMTIME systemTime;
        ::GetSystemTime(&systemTime);
        rc = timeZoneFunction(systemTime.wYear, nullptr, &timeZoneInformation);
        if (rc == TIME_ZONE_ID_INVALID)
            return 0;
    } else {
        rc = ::GetTimeZoneInformation(&timeZoneInformation);
        if (rc == TIME_ZONE_ID_INVALID)
            return 0;
    }

    int32_t bias = timeZoneInformation.Bias;

    if (rc == TIME_ZONE_ID_DAYLIGHT)
        bias += timeZoneInformation.DaylightBias;
    else if (rc == TIME_ZONE_ID_STANDARD || rc == TIME_ZONE_ID_UNKNOWN)
        bias += timeZoneInformation.StandardBias;

    return -bias * 60 * 1000;
#else
    time_t localTime = time(0);
    tm localt;
    getLocalTime(&localTime, &localt);

    // Get the difference between this time zone and UTC on the 1st of January of this year.
    localt.tm_sec = 0;
    localt.tm_min = 0;
    localt.tm_hour = 0;
    localt.tm_mday = 1;
    localt.tm_mon = 0;
    // Not setting localt.tm_year!
    localt.tm_wday = 0;
    localt.tm_yday = 0;
    localt.tm_isdst = 0;
#if HAVE(TM_GMTOFF)
    localt.tm_gmtoff = 0;
#endif
#if HAVE(TM_ZONE)
    localt.tm_zone = 0;
#endif

#if HAVE(TIMEGM)
    time_t utcOffset = timegm(&localt) - mktime(&localt);
#else
    // Using a canned date of 01/01/2019 on platforms with weaker date-handling foo.
    localt.tm_year = 119;
    time_t utcOffset = 1546300800 - mktime(&localt);
#endif

    return static_cast<int32_t>(utcOffset * 1000);
#endif
}

#if !HAVE(TM_GMTOFF)

#if OS(WINDOWS)
// Code taken from http://support.microsoft.com/kb/167296
static void UnixTimeToFileTime(time_t t, LPFILETIME pft)
{
    // Note that LONGLONG is a 64-bit value
    LONGLONG ll;

    ll = Int32x32To64(t, 10000000) + 116444736000000000;
    pft->dwLowDateTime = (DWORD)ll;
    pft->dwHighDateTime = ll >> 32;
}
#endif

/*
 * Get the DST offset for the time passed in.
 */
static double calculateDSTOffset(time_t localTime, double utcOffset)
{
    // input is UTC so we have to shift back to local time to determine DST thus the + getUTCOffset()
    double offsetTime = (localTime * msPerSecond) + utcOffset;

    // Offset from UTC but doesn't include DST obviously
    int offsetHour =  msToHours(offsetTime);
    int offsetMinute =  msToMinutes(offsetTime);

#if OS(WINDOWS)
    FILETIME utcFileTime;
    UnixTimeToFileTime(localTime, &utcFileTime);
    SYSTEMTIME utcSystemTime, localSystemTime;
    if (!::FileTimeToSystemTime(&utcFileTime, &utcSystemTime))
        return 0;
    if (!::SystemTimeToTzSpecificLocalTime(nullptr, &utcSystemTime, &localSystemTime))
        return 0;

    double diff = ((localSystemTime.wHour - offsetHour) * secondsPerHour) + ((localSystemTime.wMinute - offsetMinute) * 60);
#else
    tm localTM;
    getLocalTime(&localTime, &localTM);

    double diff = ((localTM.tm_hour - offsetHour) * secondsPerHour) + ((localTM.tm_min - offsetMinute) * 60);
#endif

    if (diff < 0)
        diff += secondsPerDay;

    return (diff * msPerSecond);
}

#endif

// 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
}

void initializeDates()
{
#if ASSERT_ENABLED
    static bool alreadyInitialized;
    ASSERT(!alreadyInitialized);
    alreadyInitialized = true;
#endif

    equivalentYearForDST(2000); // Need to call once to initialize a static used in this function.
}

static inline double ymdhmsToMilliseconds(int year, long mon, long day, long hour, long minute, long second, double milliseconds)
{
    int mday = firstDayOfMonth[isLeapYear(year)][mon - 1];
    double ydays = daysFrom1970ToYear(year);

    double dateMilliseconds = milliseconds + second * msPerSecond + minute * (secondsPerMinute * msPerSecond) + hour * (secondsPerHour * msPerSecond) + (mday + day - 1 + ydays) * (secondsPerDay * msPerSecond);

    // Clamp to EcmaScript standard (ecma262/#sec-time-values-and-time-range) of
    //  +/- 100,000,000 days from 01 January, 1970.
    if (dateMilliseconds < -8640000000000000.0 || dateMilliseconds > 8640000000000000.0)
        return std::numeric_limits<double>::quiet_NaN();
    
    return dateMilliseconds;
}

// We follow the recommendation of RFC 2822 to consider all
// obsolete time zones not listed here equivalent to "-0000".
static const struct KnownZone {
#if !OS(WINDOWS)
    const
#endif
        char tzName[4];
    int tzOffset;
} knownZones[] = {
    { "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 failure
static 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 parseInt(const char* string, char** stopPosition, int base, int* result)
{
    long longResult = strtol(string, stopPosition, base);
    // Avoid the use of errno as it is not available on Windows CE
    if (string == *stopPosition || longResult <= std::numeric_limits<int>::min() || longResult >= std::numeric_limits<int>::max())
        return false;
    *result = static_cast<int>(longResult);
    return true;
}

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 == std::numeric_limits<long>::min() || *result == std::numeric_limits<long>::max())
        return false;
    return true;
}

// Parses a date with the format YYYY[-MM[-DD]].
// Year parsing is lenient, allows any number of digits, and +/-.
// Returns 0 if a parse error occurs, else returns the end of the parsed portion of the string.
static char* parseES5DatePortion(const char* currentPosition, int& year, long& month, long& day)
{
    char* postParsePosition;

    // This is a bit more lenient on the year string than ES5 specifies:
    // instead of restricting to 4 digits (or 6 digits with mandatory +/-),
    // it accepts any integer value. Consider this an implementation fallback.
    bool hasNegativeYear = *currentPosition == '-';
    if (!parseInt(currentPosition, &postParsePosition, 10, &year))
        return nullptr;
    if (!year && hasNegativeYear)
        return nullptr;

    // Check for presence of -MM portion.
    if (*postParsePosition != '-')
        return postParsePosition;
    currentPosition = postParsePosition + 1;
    
    if (!isASCIIDigit(*currentPosition))
        return nullptr;
    if (!parseLong(currentPosition, &postParsePosition, 10, &month))
        return nullptr;
    if ((postParsePosition - currentPosition) != 2)
        return nullptr;

    // Check for presence of -DD portion.
    if (*postParsePosition != '-')
        return postParsePosition;
    currentPosition = postParsePosition + 1;
    
    if (!isASCIIDigit(*currentPosition))
        return nullptr;
    if (!parseLong(currentPosition, &postParsePosition, 10, &day))
        return nullptr;
    if ((postParsePosition - currentPosition) != 2)
        return nullptr;
    return postParsePosition;
}

// Parses a time with the format HH:mm[:ss[.sss]][Z|(+|-)(00:00|0000|00)].
// Fractional seconds parsing is lenient, allows any number of digits.
// Returns 0 if a parse error occurs, else returns the end of the parsed portion of the string.
static char* parseES5TimePortion(char* currentPosition, long& hours, long& minutes, long& seconds, double& milliseconds, bool& isLocalTime, long& timeZoneSeconds)
{
    isLocalTime = false;

    char* postParsePosition;
    if (!isASCIIDigit(*currentPosition))
        return nullptr;
    if (!parseLong(currentPosition, &postParsePosition, 10, &hours))
        return nullptr;
    if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2)
        return nullptr;
    currentPosition = postParsePosition + 1;
    
    if (!isASCIIDigit(*currentPosition))
        return nullptr;
    if (!parseLong(currentPosition, &postParsePosition, 10, &minutes))
        return nullptr;
    if ((postParsePosition - currentPosition) != 2)
        return nullptr;
    currentPosition = postParsePosition;

    // Seconds are optional.
    if (*currentPosition == ':') {
        ++currentPosition;
    
        if (!isASCIIDigit(*currentPosition))
            return nullptr;
        if (!parseLong(currentPosition, &postParsePosition, 10, &seconds))
            return nullptr;
        if ((postParsePosition - currentPosition) != 2)
            return nullptr;
        if (*postParsePosition == '.') {
            currentPosition = postParsePosition + 1;
            
            // In ECMA-262-5 it's a bit unclear if '.' can be present without milliseconds, but
            // a reasonable interpretation guided by the given examples and RFC 3339 says "no".
            // We check the next character to avoid reading +/- timezone hours after an invalid decimal.
            if (!isASCIIDigit(*currentPosition))
                return nullptr;
            
            // We are more lenient than ES5 by accepting more or less than 3 fraction digits.
            long fracSeconds;
            if (!parseLong(currentPosition, &postParsePosition, 10, &fracSeconds))
                return nullptr;
            
            long numFracDigits = postParsePosition - currentPosition;
            milliseconds = fracSeconds * pow(10.0, static_cast<double>(-numFracDigits + 3));
        }
        currentPosition = postParsePosition;
    }

    if (*currentPosition == 'Z')
        return currentPosition + 1;

    // Parse (+|-)(00:00|0000|00).
    bool tzNegative;
    if (*currentPosition == '-')
        tzNegative = true;
    else if (*currentPosition == '+')
        tzNegative = false;
    else {
        isLocalTime = true;
        return currentPosition;
    }
    ++currentPosition;
    
    long tzHours = 0;
    long tzHoursAbs = 0;
    long tzMinutes = 0;
    
    if (!isASCIIDigit(*currentPosition))
        return nullptr;
    if (!parseLong(currentPosition, &postParsePosition, 10, &tzHours))
        return nullptr;
    if (*postParsePosition != ':') {
        if ((postParsePosition - currentPosition) == 2) {
            // "00" case.
            tzHoursAbs = labs(tzHours);
        } else if ((postParsePosition - currentPosition) == 4) {
            // "0000" case.
            tzHoursAbs = labs(tzHours);
            tzMinutes = tzHoursAbs % 100;
            tzHoursAbs = tzHoursAbs / 100;
        } else
            return nullptr;
    } else {
        // "00:00" case.
        if ((postParsePosition - currentPosition) != 2)
            return nullptr;
        tzHoursAbs = labs(tzHours);
        currentPosition = postParsePosition + 1; // Skip ":".
    
        if (!isASCIIDigit(*currentPosition))
            return nullptr;
        if (!parseLong(currentPosition, &postParsePosition, 10, &tzMinutes))
            return nullptr;
        if ((postParsePosition - currentPosition) != 2)
            return nullptr;
    }
    currentPosition = postParsePosition;
    
    if (tzHoursAbs > 24)
        return nullptr;
    if (tzMinutes < 0 || tzMinutes > 59)
        return nullptr;
    
    timeZoneSeconds = 60 * (tzMinutes + (60 * tzHoursAbs));
    if (tzNegative)
        timeZoneSeconds = -timeZoneSeconds;

    return currentPosition;
}

double parseES5DateFromNullTerminatedCharacters(const char* dateString, bool& isLocalTime)
{
    isLocalTime = false;

    // This parses a date of the form defined in ecma262/#sec-date-time-string-format
    // (similar to RFC 3339 / ISO 8601: YYYY-MM-DDTHH:mm:ss[.sss]Z).
    // In most cases it is intentionally strict (e.g. correct field widths, no stray whitespace).
    
    static const long daysPerMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    
    // The year must be present, but the other fields may be omitted - see ES5.1 15.9.1.15.
    int year = 0;
    long month = 1;
    long day = 1;
    long hours = 0;
    long minutes = 0;
    long seconds = 0;
    double milliseconds = 0;
    long timeZoneSeconds = 0;

    // Parse the date YYYY[-MM[-DD]]
    char* currentPosition = parseES5DatePortion(dateString, year, month, day);
    if (!currentPosition)
        return std::numeric_limits<double>::quiet_NaN();
    // Look for a time portion.
    // Note: As of ES2016, when a UTC offset is missing, date-time forms are local time while date-only forms are UTC.
    if (*currentPosition == 'T' || *currentPosition == 't' || *currentPosition == ' ') {
        // Parse the time HH:mm[:ss[.sss]][Z|(+|-)(00:00|0000|00)]
        currentPosition = parseES5TimePortion(currentPosition + 1, hours, minutes, seconds, milliseconds, isLocalTime, timeZoneSeconds);
        if (!currentPosition)
            return std::numeric_limits<double>::quiet_NaN();
    }
    // Check that we have parsed all characters in the string.
    if (*currentPosition)
        return std::numeric_limits<double>::quiet_NaN();

    // A few of these checks could be done inline above, but since many of them are interrelated
    // we would be sacrificing readability to "optimize" the (presumably less common) failure path.
    if (month < 1 || month > 12)
        return std::numeric_limits<double>::quiet_NaN();
    if (day < 1 || day > daysPerMonth[month - 1])
        return std::numeric_limits<double>::quiet_NaN();
    if (month == 2 && day > 28 && !isLeapYear(year))
        return std::numeric_limits<double>::quiet_NaN();
    if (hours < 0 || hours > 24)
        return std::numeric_limits<double>::quiet_NaN();
    if (hours == 24 && (minutes || seconds))
        return std::numeric_limits<double>::quiet_NaN();
    if (minutes < 0 || minutes > 59)
        return std::numeric_limits<double>::quiet_NaN();
    if (seconds < 0 || seconds >= 61)
        return std::numeric_limits<double>::quiet_NaN();
    if (seconds == 60) {
        // Discard leap seconds by clamping to the end of a minute.
        milliseconds = 0;
    }
        
    return ymdhmsToMilliseconds(year, month, day, hours, minutes, seconds, milliseconds) - (timeZoneSeconds * msPerSecond);
}

// Odd case where 'exec' is allowed to be 0, to accomodate a caller in WebCore.
double parseDateFromNullTerminatedCharacters(const char* dateString, bool& isLocalTime)
{
    isLocalTime = true;
    int offset = 0;

    // 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.
     
    // 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 std::numeric_limits<double>::quiet_NaN();

    // ' 09-Nov-99 23:12:40 GMT'
    char* newPosStr;
    long day;
    if (!parseLong(dateString, &newPosStr, 10, &day))
        return std::numeric_limits<double>::quiet_NaN();
    dateString = newPosStr;

    if (day < 0)
        return std::numeric_limits<double>::quiet_NaN();

    std::optional<int> year;
    if (day > 31) {
        // ### where is the boundary and what happens below?
        if (*dateString != '/')
            return std::numeric_limits<double>::quiet_NaN();
        // looks like a YYYY/MM/DD date
        if (!*++dateString)
            return std::numeric_limits<double>::quiet_NaN();
        if (day <= std::numeric_limits<int>::min() || day >= std::numeric_limits<int>::max())
            return std::numeric_limits<double>::quiet_NaN();
        year = static_cast<int>(day);
        if (!parseLong(dateString, &newPosStr, 10, &month))
            return std::numeric_limits<double>::quiet_NaN();
        month -= 1;
        dateString = newPosStr;
        if (*dateString++ != '/' || !*dateString)
            return std::numeric_limits<double>::quiet_NaN();
        if (!parseLong(dateString, &newPosStr, 10, &day))
            return std::numeric_limits<double>::quiet_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 std::numeric_limits<double>::quiet_NaN();
        if (day < 1 || day > 31)
            return std::numeric_limits<double>::quiet_NaN();
        dateString = newPosStr;
        if (*dateString == '/')
            dateString++;
        if (!*dateString)
            return std::numeric_limits<double>::quiet_NaN();
     } else {
        if (*dateString == '-')
            dateString++;

        skipSpacesAndComments(dateString);

        if (*dateString == ',')
            dateString++;

        if (month == -1) { // not found yet
            month = findMonth(dateString);
            if (month == -1)
                return std::numeric_limits<double>::quiet_NaN();

            while (*dateString && *dateString != '-' && *dateString != ',' && !isASCIISpace(*dateString))
                dateString++;

            if (!*dateString)
                return std::numeric_limits<double>::quiet_NaN();

            // '-99 23:12:40 GMT'
            if (*dateString != '-' && *dateString != '/' && *dateString != ',' && !isASCIISpace(*dateString))
                return std::numeric_limits<double>::quiet_NaN();
            dateString++;
        }
    }

    if (month < 0 || month > 11)
        return std::numeric_limits<double>::quiet_NaN();

    // '99 23:12:40 GMT'
    if (*dateString && !year) {
        int result = 0;
        if (!parseInt(dateString, &newPosStr, 10, &result))
            return std::numeric_limits<double>::quiet_NaN();
        year = result;
    }

    // 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 std::numeric_limits<double>::quiet_NaN();
            // There was no year; the number was the hour.
            year = std::nullopt;
        } else {
            // in the normal case (we parsed the year), advance to the next number
            // ' at 23:12:40 GMT'
            if (isASCIISpace(newPosStr[0]) && isASCIIAlphaCaselessEqual(newPosStr[1], 'a') && isASCIIAlphaCaselessEqual(newPosStr[2], 't'))
                newPosStr += 3;
            else
                ++newPosStr; // space or comma
            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 std::numeric_limits<double>::quiet_NaN();

            if (!*dateString)
                return std::numeric_limits<double>::quiet_NaN();

            // ':12:40 GMT'
            if (*dateString++ != ':')
                return std::numeric_limits<double>::quiet_NaN();

            if (!parseLong(dateString, &newPosStr, 10, &minute))
                return std::numeric_limits<double>::quiet_NaN();
            dateString = newPosStr;

            if (minute < 0 || minute > 59)
                return std::numeric_limits<double>::quiet_NaN();

            // ':40 GMT'
            if (*dateString && *dateString != ':' && !isASCIISpace(*dateString))
                return std::numeric_limits<double>::quiet_NaN();

            // seconds are optional in rfc822 + rfc2822
            if (*dateString ==':') {
                dateString++;

                if (!parseLong(dateString, &newPosStr, 10, &second))
                    return std::numeric_limits<double>::quiet_NaN();
                dateString = newPosStr;

                if (second < 0 || second > 59)
                    return std::numeric_limits<double>::quiet_NaN();
            }

            skipSpacesAndComments(dateString);

            if (startsWithLettersIgnoringASCIICase(StringView::fromLatin1(dateString), "am"_s)) {
                if (hour > 12)
                    return std::numeric_limits<double>::quiet_NaN();
                if (hour == 12)
                    hour = 0;
                dateString += 2;
                skipSpacesAndComments(dateString);
            } else if (startsWithLettersIgnoringASCIICase(StringView::fromLatin1(dateString), "pm"_s)) {
                if (hour > 12)
                    return std::numeric_limits<double>::quiet_NaN();
                if (hour != 12)
                    hour += 12;
                dateString += 2;
                skipSpacesAndComments(dateString);
            }
        }
    }
    
    // The year may be after the time but before the time zone.
    if (isASCIIDigit(*dateString) && !year) {
        int result = 0;
        if (!parseInt(dateString, &newPosStr, 10, &result))
            return std::numeric_limits<double>::quiet_NaN();
        year = result;
        dateString = newPosStr;
        skipSpacesAndComments(dateString);
    }

    // Don't fail if the time zone is missing. 
    // Some websites omit the time zone (4275206).
    if (*dateString) {
        if (startsWithLettersIgnoringASCIICase(StringView ::fromLatin1(dateString), "gmt"_s) || startsWithLettersIgnoringASCIICase(StringView::fromLatin1(dateString), "utc"_s)) {
            dateString += 3;
            isLocalTime = false;
        }

        if (*dateString == '+' || *dateString == '-') {
            int o;
            if (!parseInt(dateString, &newPosStr, 10, &o))
                return std::numeric_limits<double>::quiet_NaN();
            dateString = newPosStr;

            if (o < -9959 || o > 9959)
                return std::numeric_limits<double>::quiet_NaN();

            int sgn = (o < 0) ? -1 : 1;
            o = abs(o);
            if (*dateString != ':') {
                if (o >= 24)
                    offset = ((o / 100) * 60 + (o % 100)) * sgn;
                else
                    offset = o * 60 * sgn;
            } else { // GMT+05:00
                ++dateString; // skip the ':'
                int o2;
                if (!parseInt(dateString, &newPosStr, 10, &o2))
                    return std::numeric_limits<double>::quiet_NaN();
                dateString = newPosStr;
                offset = (o * 60 + o2) * sgn;
            }
            isLocalTime = false;
        } else {
            for (auto& knownZone : knownZones) {
                // Since the passed-in length is used for both strings, the following checks that
                // dateString has the time zone name as a prefix, not that it is equal.
                auto length = strlen(knownZone.tzName);
                if (equalLettersIgnoringASCIICase(dateString, knownZone.tzName, length)) {
                    offset = knownZone.tzOffset;
                    dateString += length;
                    isLocalTime = false;
                    break;
                }
            }
        }
    }

    skipSpacesAndComments(dateString);

    if (*dateString && !year) {
        int result = 0;
        if (!parseInt(dateString, &newPosStr, 10, &result))
            return std::numeric_limits<double>::quiet_NaN();
        year = result;
        dateString = newPosStr;
        skipSpacesAndComments(dateString);
    }

    // Trailing garbage
    if (*dateString)
        return std::numeric_limits<double>::quiet_NaN();

    // Y2K: Handle 2 digit years.
    if (year) {
        int yearValue = year.value();
        if (yearValue >= 0 && yearValue < 100) {
            if (yearValue < 50)
                yearValue += 2000;
            else
                yearValue += 1900;
        }
        year = yearValue;
    } else {
        // We select 2000 as default value. This is because of the following reasons.
        // 1. Year 2000 was used for the initial value of the variable `year`. While it won't be posed to users in WebKit,
        //    V8 used this 2000 as its default value. (As of April 2017, V8 is using the year 2001 and Spider Monkey is
        //    not doing this kind of fallback.)
        // 2. It is a leap year. When using `new Date("Feb 29")`, we assume that people want to save month and day.
        //    Leap year can save user inputs if they is valid. If we use the current year instead, the current year
        //    may not be a leap year. In that case, `new Date("Feb 29").getMonth()` becomes 2 (March).
        year = 2000;
    }
    ASSERT(year);

    return ymdhmsToMilliseconds(year.value(), month + 1, day, hour, minute, second, 0) - offset * (secondsPerMinute * msPerSecond);
}

double parseDateFromNullTerminatedCharacters(const char* dateString)
{
    bool isLocalTime;
    double value = parseDateFromNullTerminatedCharacters(dateString, isLocalTime);

    if (isLocalTime)
        value -= calculateLocalTimeOffset(value, LocalTime).offset;

    return value;
}

// See http://tools.ietf.org/html/rfc2822#section-3.3 for more information.
String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, unsigned year, unsigned hours, unsigned minutes, unsigned seconds, int utcOffset)
{
    StringBuilder stringBuilder;
    stringBuilder.append(weekdayName[dayOfWeek], ", ", day, ' ', monthName[month], ' ', year, ' ');

    appendTwoDigitNumber(stringBuilder, hours);
    stringBuilder.append(':');
    appendTwoDigitNumber(stringBuilder, minutes);
    stringBuilder.append(':');
    appendTwoDigitNumber(stringBuilder, seconds);
    stringBuilder.append(' ');

    stringBuilder.append(utcOffset > 0 ? '+' : '-');
    int absoluteUTCOffset = abs(utcOffset);
    appendTwoDigitNumber(stringBuilder, absoluteUTCOffset / 60);
    appendTwoDigitNumber(stringBuilder, absoluteUTCOffset % 60);

    return stringBuilder.toString();
}

static std::optional<Vector<UChar, 32>> validateTimeZone(StringView timeZone)
{
    Vector<UChar, 32> buffer(timeZone.length());
    timeZone.getCharactersWithUpconvert(buffer.data());

    Vector<UChar, 32> canonicalBuffer;
    auto status = callBufferProducingFunction(ucal_getCanonicalTimeZoneID, buffer.data(), buffer.size(), canonicalBuffer, nullptr);
    if (!U_SUCCESS(status))
        return std::nullopt;
    return canonicalBuffer;
}

bool isTimeZoneValid(StringView timeZone)
{
    return validateTimeZone(timeZone).has_value();
}

bool setTimeZoneOverride(StringView timeZone)
{
    if (timeZone.isEmpty()) {
        Locker locker { innerTimeZoneOverrideLock };
        innerTimeZoneOverride().clear();
        return true;
    }

    auto canonicalBuffer = validateTimeZone(timeZone);
    if (!canonicalBuffer)
        return false;

    {
        Locker locker { innerTimeZoneOverrideLock };
        innerTimeZoneOverride() = WTFMove(*canonicalBuffer);
    }
    return true;
}

void getTimeZoneOverride(Vector<UChar, 32>& timeZoneID)
{
    Locker locker { innerTimeZoneOverrideLock };
    timeZoneID = innerTimeZoneOverride();
}

} // namespace WTF
