Changeset 44508 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Jun 8, 2009, 3:37:06 PM (16 years ago)
Author:
Dimitri Glazkov
Message:

JavaScriptCore:

2009-06-08 Dimitri Glazkov <Dimitri Glazkov>

Reviewed by Eric Seidel.

https://bugs.webkit.org/show_bug.cgi?id=26238
Move most of runtime/DateMath functions to wtf/DateMath, and split off conversion-related
helpers to DateConversion.

  • AllInOneFile.cpp: Changed DateMath->DateConversion.
  • GNUmakefile.am: Ditto and added DateMath.
  • JavaScriptCore.exp: Ditto.
  • JavaScriptCore.pri: Ditto.
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto.
  • JavaScriptCore.vcproj/WTF/WTF.vcproj: Added DateMath.
  • JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
  • JavaScriptCoreSources.bkl: Ditto.
  • pcre/pcre_exec.cpp: Changed to use DateMath.
  • profiler/ProfileNode.cpp: (JSC::getCount): Changed to use DateConversion.
  • runtime/DateConstructor.cpp: Ditto.
  • runtime/DateConversion.cpp: Copied from JavaScriptCore/runtime/DateMath.cpp. (JSC::parseDate): Refactored to use null-terminated characters as input.
  • runtime/DateConversion.h: Copied from JavaScriptCore/runtime/DateMath.h.
  • runtime/DateInstance.cpp: Changed to use wtf/DateMath.
  • runtime/DateInstance.h: Ditto.
  • runtime/DateMath.cpp: Removed.
  • runtime/DateMath.h: Removed.
  • runtime/DatePrototype.cpp: Ditto.
  • runtime/InitializeThreading.cpp: Ditto.
  • wtf/DateMath.cpp: Copied from JavaScriptCore/runtime/DateMath.cpp.
  • wtf/DateMath.h: Copied from JavaScriptCore/runtime/DateMath.h.

WebCore:

2009-06-08 Dimitri Glazkov <Dimitri Glazkov>

Reviewed by Eric Seidel.

https://bugs.webkit.org/show_bug.cgi?id=26238
Add parseDate helper to HTTPParsers, which uses WTF::parseDateFromNullTerminatedCharacters.

  • ForwardingHeaders/runtime/DateMath.h: Removed.
  • ForwardingHeaders/wtf/DateMath.h: Copied from WebCore/ForwardingHeaders/runtime/DateMath.h.
  • platform/network/HTTPParsers.cpp: (WebCore::parseDate): Added.
  • platform/network/HTTPParsers.h:
  • platform/network/ResourceResponseBase.cpp: (WebCore::parseDateValueInHeader): Changed to use the new helper.
Location:
trunk/JavaScriptCore
Files:
16 edited
2 copied
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/AllInOneFile.cpp

    r44224 r44508  
    4848#include "runtime/CommonIdentifiers.cpp"
    4949#include "runtime/DateConstructor.cpp"
    50 #include "runtime/DateMath.cpp"
     50#include "runtime/DateConversion.cpp"
    5151#include "runtime/DatePrototype.cpp"
    5252#include "runtime/DateInstance.cpp"
  • trunk/JavaScriptCore/ChangeLog

    r44506 r44508  
     12009-06-08  Dimitri Glazkov  <[email protected]>
     2
     3        Reviewed by Eric Seidel.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=26238
     6        Move most of runtime/DateMath functions to wtf/DateMath, and split off conversion-related
     7        helpers to DateConversion.
     8
     9        * AllInOneFile.cpp: Changed DateMath->DateConversion.
     10        * GNUmakefile.am: Ditto and added DateMath.
     11        * JavaScriptCore.exp: Ditto.
     12        * JavaScriptCore.pri: Ditto.
     13        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto.
     14        * JavaScriptCore.vcproj/WTF/WTF.vcproj: Added DateMath.
     15        * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
     16        * JavaScriptCoreSources.bkl: Ditto.
     17        * pcre/pcre_exec.cpp: Changed to use DateMath.
     18        * profiler/ProfileNode.cpp:
     19        (JSC::getCount): Changed to use DateConversion.
     20        * runtime/DateConstructor.cpp: Ditto.
     21        * runtime/DateConversion.cpp: Copied from JavaScriptCore/runtime/DateMath.cpp.
     22        (JSC::parseDate): Refactored to use null-terminated characters as input.
     23        * runtime/DateConversion.h: Copied from JavaScriptCore/runtime/DateMath.h.
     24        * runtime/DateInstance.cpp: Changed to use wtf/DateMath.
     25        * runtime/DateInstance.h: Ditto.
     26        * runtime/DateMath.cpp: Removed.
     27        * runtime/DateMath.h: Removed.
     28        * runtime/DatePrototype.cpp: Ditto.
     29        * runtime/InitializeThreading.cpp: Ditto.
     30        * wtf/DateMath.cpp: Copied from JavaScriptCore/runtime/DateMath.cpp.
     31        * wtf/DateMath.h: Copied from JavaScriptCore/runtime/DateMath.h.
     32
    1332009-06-08  Steve Falkenburg  <[email protected]>
    234
  • trunk/JavaScriptCore/GNUmakefile.am

    r44197 r44508  
    369369        JavaScriptCore/runtime/DateConstructor.cpp \
    370370        JavaScriptCore/runtime/DateConstructor.h \
     371        JavaScriptCore/runtime/DateConversion.cpp \
     372        JavaScriptCore/runtime/DateConversion.h \
    371373        JavaScriptCore/runtime/DateInstance.cpp \
    372374        JavaScriptCore/runtime/DateInstance.h \
    373         JavaScriptCore/runtime/DateMath.cpp \
    374         JavaScriptCore/runtime/DateMath.h \
    375375        JavaScriptCore/runtime/DatePrototype.cpp \
    376376        JavaScriptCore/runtime/DatePrototype.h \
     
    478478        JavaScriptCore/runtime/UString.cpp \
    479479        JavaScriptCore/runtime/UString.h \
     480        JavaScriptCore/wtf/DateMath.cpp \
     481        JavaScriptCore/wtf/DateMath.h \
    480482        JavaScriptCore/wtf/FastAllocBase.h \
    481483        JavaScriptCore/wtf/FastMalloc.cpp \
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r44452 r44508  
    276276__ZN3JSC9StructureD1Ev
    277277__ZN3JSC9constructEPNS_9ExecStateENS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
    278 __ZN3JSC9parseDateERKNS_7UStringE
    279278__ZN3JSCeqERKNS_7UStringEPKc
    280279__ZN3JSCgtERKNS_7UStringES2_
     
    290289__ZN3WTF12randomNumberEv
    291290__ZN3WTF13currentThreadEv
     291__ZN3WTF37parseDateFromNullTerminatedCharactersEPKc
    292292__ZN3WTF13tryFastCallocEmm
    293293__ZN3WTF15ThreadCondition4waitERNS_5MutexE
  • trunk/JavaScriptCore/JavaScriptCore.pri

    r44496 r44508  
    153153    wtf/CurrentTime.cpp \
    154154    runtime/DateConstructor.cpp \
     155    runtime/DateConversion.cpp \
    155156    runtime/DateInstance.cpp \
    156     runtime/DateMath.cpp \
    157157    runtime/DatePrototype.cpp \
    158158    debugger/Debugger.cpp \
     
    219219    profiler/Profiler.cpp \
    220220    profiler/TreeProfile.cpp \
     221    wtf/DateMath.cpp \
    221222    wtf/FastMalloc.cpp \
    222223    wtf/Threading.cpp \
  • trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

    r44117 r44508  
    597597                        </File>
    598598                        <File
    599                                 RelativePath="..\..\runtime\DateMath.cpp"
    600                                 >
    601                         </File>
    602                         <File
    603                                 RelativePath="..\..\runtime\DateMath.h"
     599                                RelativePath="..\..\runtime\DateConversion.cpp"
     600                                >
     601                        </File>
     602                        <File
     603                                RelativePath="..\..\runtime\DateConversion.h"
    604604                                >
    605605                        </File>
  • trunk/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj

    r44145 r44508  
    234234                </File>
    235235                <File
     236                        RelativePath="..\..\wtf\DateMath.cpp"
     237                        >
     238                </File>
     239                <File
     240                        RelativePath="..\..\wtf\DateMath.h"
     241                        >
     242                </File>
     243                <File
    236244                        RelativePath="..\..\wtf\Deque.h"
    237245                        >
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r44504 r44508  
    101101                1C61516C0EBAC7A00031376F /* ProfilerServer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C61516A0EBAC7A00031376F /* ProfilerServer.mm */; settings = {COMPILER_FLAGS = "-fno-strict-aliasing"; }; };
    102102                1C61516D0EBAC7A00031376F /* ProfilerServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C61516B0EBAC7A00031376F /* ProfilerServer.h */; };
     103                41359CF30FDD89AD00206180 /* DateConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateConversion.h */; };
     104                41359CF60FDD89CB00206180 /* DateMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41359CF40FDD89CB00206180 /* DateMath.cpp */; };
     105                41359CF70FDD89CB00206180 /* DateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 41359CF50FDD89CB00206180 /* DateMath.h */; settings = {ATTRIBUTES = (Private, ); }; };
    103106                4409D8470FAF80A200523B87 /* OwnPtrCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 440B7AED0FAF7FCB0073323E /* OwnPtrCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
    104107                44DD48530FAEA85000D6B4EB /* PassOwnPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 44DD48520FAEA85000D6B4EB /* PassOwnPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    217220                BC18C3F50E16F5CD00B34460 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = F68EBB8C0255D4C601FF60F7 /* config.h */; settings = {ATTRIBUTES = (Private, ); }; };
    218221                BC18C3F60E16F5CD00B34460 /* ConstructData.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8F3CCF0DAF17BA00577A80 /* ConstructData.h */; settings = {ATTRIBUTES = (Private, ); }; };
    219                 BC18C3F90E16F5CD00B34460 /* DateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateMath.h */; settings = {ATTRIBUTES = (Private, ); }; };
    220222                BC18C3FA0E16F5CD00B34460 /* Debugger.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8590255597D01FF60F7 /* Debugger.h */; settings = {ATTRIBUTES = (Private, ); }; };
    221223                BC18C3FB0E16F5CD00B34460 /* DebuggerCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1480DB9B0DDC227F003CFDF2 /* DebuggerCallFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    549551                1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScript.h; sourceTree = "<group>"; };
    550552                1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptCore.h; sourceTree = "<group>"; };
     553                41359CF40FDD89CB00206180 /* DateMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DateMath.cpp; sourceTree = "<group>"; };
     554                41359CF50FDD89CB00206180 /* DateMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateMath.h; sourceTree = "<group>"; };
    551555                440B7AED0FAF7FCB0073323E /* OwnPtrCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnPtrCommon.h; sourceTree = "<group>"; };
    552556                449097EE0F8F81B50076A327 /* FeatureDefines.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FeatureDefines.xcconfig; sourceTree = "<group>"; };
     
    822826                BCFD8C910EEB2EE700283848 /* JumpTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JumpTable.h; sourceTree = "<group>"; };
    823827                C0A2723F0E509F1E00E96E15 /* NotFound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotFound.h; sourceTree = "<group>"; };
    824                 D21202280AD4310C00ED79B6 /* DateMath.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateMath.cpp; sourceTree = "<group>"; };
    825                 D21202290AD4310C00ED79B6 /* DateMath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateMath.h; sourceTree = "<group>"; };
     828                D21202280AD4310C00ED79B6 /* DateConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateConversion.cpp; sourceTree = "<group>"; };
     829                D21202290AD4310C00ED79B6 /* DateConversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateConversion.h; sourceTree = "<group>"; };
    826830                E11D51750B2E798D0056C188 /* StringExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringExtras.h; sourceTree = "<group>"; };
    827831                E124A8F50E555775003091F1 /* OpaqueJSString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueJSString.h; sourceTree = "<group>"; };
     
    11651169                                180B9AEF0F16C569009BDBC5 /* CurrentTime.cpp */,
    11661170                                180B9AF00F16C569009BDBC5 /* CurrentTime.h */,
     1171                                41359CF40FDD89CB00206180 /* DateMath.cpp */,
     1172                                41359CF50FDD89CB00206180 /* DateMath.h */,
    11671173                                5186111D0CC824830081412B /* Deque.h */,
    11681174                                938C4F6B0CA06BCE00D9310A /* DisallowCType.h */,
     
    13201326                                BC1166000E1997B1008066DD /* DateInstance.cpp */,
    13211327                                BC1166010E1997B1008066DD /* DateInstance.h */,
    1322                                 D21202280AD4310C00ED79B6 /* DateMath.cpp */,
    1323                                 D21202290AD4310C00ED79B6 /* DateMath.h */,
     1328                                D21202280AD4310C00ED79B6 /* DateConversion.cpp */,
     1329                                D21202290AD4310C00ED79B6 /* DateConversion.h */,
    13241330                                BCD203470E17135E002C7E82 /* DatePrototype.cpp */,
    13251331                                BCD203480E17135E002C7E82 /* DatePrototype.h */,
     
    16271633                                180B9B080F16D94F009BDBC5 /* CurrentTime.h in Headers */,
    16281634                                BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
     1635                                41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
    16291636                                BC1166020E1997B4008066DD /* DateInstance.h in Headers */,
    1630                                 BC18C3F90E16F5CD00B34460 /* DateMath.h in Headers */,
     1637                                41359CF70FDD89CB00206180 /* DateMath.h in Headers */,
    16311638                                BCD2034C0E17135E002C7E82 /* DatePrototype.h in Headers */,
    16321639                                BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */,
     
    21262133                                E1A862A90D7EBB76001EC6AA /* CollatorICU.cpp in Sources */,
    21272134                                180B9BFE0F16E94D009BDBC5 /* CurrentTime.cpp in Sources */,
     2135                                41359CF60FDD89CB00206180 /* DateMath.cpp in Sources */,
    21282136                                149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */,
    21292137                                1429D8780ED21ACD00B89619 /* ExceptionHelpers.cpp in Sources */,
  • trunk/JavaScriptCore/JavaScriptCoreSources.bkl

    r43591 r44508  
    8888        runtime/ConstructData.cpp
    8989        runtime/DateConstructor.cpp
     90        runtime/DateConversion.cpp
    9091        runtime/DateInstance.cpp
    91         runtime/DateMath.cpp
    9292        runtime/DatePrototype.cpp
    9393        runtime/Error.cpp
     
    172172        wtf/ByteArray.cpp
    173173        wtf/CurrentTime.cpp
     174        wtf/DateMath.cpp
    174175        wtf/FastMalloc.cpp
    175176        wtf/HashTable.cpp
  • trunk/JavaScriptCore/pcre/pcre_exec.cpp

    r41849 r44508  
    5151
    5252#if REGEXP_HISTOGRAM
    53 #include <parser/DateMath.h>
     53#include <wtf/DateMath.h>
    5454#include <runtime/UString.h>
    5555#endif
  • trunk/JavaScriptCore/profiler/ProfileNode.cpp

    r42808 r44508  
    3030#include "ProfileNode.h"
    3131
    32 #include "DateMath.h"
    3332#include "Profiler.h"
    3433#include <stdio.h>
     34#include <wtf/DateMath.h>
    3535
    3636#if PLATFORM(WIN_OS)
     
    5050    return static_cast<double>(counter.QuadPart) / frequency.QuadPart;
    5151#else
    52     return getCurrentUTCTimeWithMicroseconds();
     52    return WTF::getCurrentUTCTimeWithMicroseconds();
    5353#endif
    5454}
  • trunk/JavaScriptCore/runtime/DateConstructor.cpp

    r43372 r44508  
    2323#include "DateConstructor.h"
    2424
     25#include "DateConversion.h"
    2526#include "DateInstance.h"
    26 #include "DateMath.h"
    2727#include "DatePrototype.h"
    2828#include "JSFunction.h"
     
    3333#include <math.h>
    3434#include <time.h>
     35#include <wtf/DateMath.h>
    3536#include <wtf/MathExtras.h>
    3637
     
    4243#include <sys/timeb.h>
    4344#endif
     45
     46using WTF::GregorianDateTime;
    4447
    4548namespace JSC {
  • trunk/JavaScriptCore/runtime/DateConversion.cpp

    r44501 r44508  
    22 * Copyright (C) 1999-2000 Harri Porten ([email protected])
    33 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
    4  *
     4 * Copyright (C) 2009 Google Inc. All rights reserved.
     5 *
    56 * The Original Code is Mozilla Communicator client code, released
    67 * March 31, 1998.
     
    4142
    4243#include "config.h"
    43 #include "DateMath.h"
     44#include "DateConversion.h"
    4445
    45 #include "JSNumberCell.h"
    46 #include <math.h>
    47 #include <stdint.h>
    48 #include <time.h>
    49 #include <wtf/ASCIICType.h>
    50 #include <wtf/Assertions.h>
    51 #include <wtf/CurrentTime.h>
    52 #include <wtf/MathExtras.h>
    53 #include <wtf/StringExtras.h>
    54 
    55 #if HAVE(ERRNO_H)
    56 #include <errno.h>
    57 #endif
    58 
    59 #if PLATFORM(DARWIN)
    60 #include <notify.h>
    61 #endif
    62 
    63 #if HAVE(SYS_TIME_H)
    64 #include <sys/time.h>
    65 #endif
    66 
    67 #if HAVE(SYS_TIMEB_H)
    68 #include <sys/timeb.h>
    69 #endif
     46#include <wtf/DateMath.h>
    7047
    7148using namespace WTF;
     
    7350namespace JSC {
    7451
    75 /* Constants */
    76 
    77 static const double minutesPerDay = 24.0 * 60.0;
    78 static const double secondsPerDay = 24.0 * 60.0 * 60.0;
    79 static const double secondsPerYear = 24.0 * 60.0 * 60.0 * 365.0;
    80 
    81 static const double usecPerSec = 1000000.0;
    82 
    83 static const double maxUnixTime = 2145859200.0; // 12/31/2037
    84 
    85 // Day of year for the first day of each month, where index 0 is January, and day 0 is January 1.
    86 // First for non-leap years, then for leap years.
    87 static const int firstDayOfMonth[2][12] = {
    88     {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
    89     {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
    90 };
    91 
    92 static inline bool isLeapYear(int year)
    93 {
    94     if (year % 4 != 0)
    95         return false;
    96     if (year % 400 == 0)
    97         return true;
    98     if (year % 100 == 0)
    99         return false;
    100     return true;
    101 }
    102 
    103 static inline int daysInYear(int year)
    104 {
    105     return 365 + isLeapYear(year);
    106 }
    107 
    108 static inline double daysFrom1970ToYear(int year)
    109 {
    110     // The Gregorian Calendar rules for leap years:
    111     // Every fourth year is a leap year.  2004, 2008, and 2012 are leap years.
    112     // However, every hundredth year is not a leap year.  1900 and 2100 are not leap years.
    113     // Every four hundred years, there's a leap year after all.  2000 and 2400 are leap years.
    114 
    115     static const int leapDaysBefore1971By4Rule = 1970 / 4;
    116     static const int excludedLeapDaysBefore1971By100Rule = 1970 / 100;
    117     static const int leapDaysBefore1971By400Rule = 1970 / 400;
    118 
    119     const double yearMinusOne = year - 1;
    120     const double yearsToAddBy4Rule = floor(yearMinusOne / 4.0) - leapDaysBefore1971By4Rule;
    121     const double yearsToExcludeBy100Rule = floor(yearMinusOne / 100.0) - excludedLeapDaysBefore1971By100Rule;
    122     const double yearsToAddBy400Rule = floor(yearMinusOne / 400.0) - leapDaysBefore1971By400Rule;
    123 
    124     return 365.0 * (year - 1970) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule;
    125 }
    126 
    127 static inline double msToDays(double ms)
    128 {
    129     return floor(ms / msPerDay);
    130 }
    131 
    132 static inline int msToYear(double ms)
    133 {
    134     int approxYear = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970);
    135     double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear);
    136     if (msFromApproxYearTo1970 > ms)
    137         return approxYear - 1;
    138     if (msFromApproxYearTo1970 + msPerDay * daysInYear(approxYear) <= ms)
    139         return approxYear + 1;
    140     return approxYear;
    141 }
    142 
    143 static inline int dayInYear(double ms, int year)
    144 {
    145     return static_cast<int>(msToDays(ms) - daysFrom1970ToYear(year));
    146 }
    147 
    148 static inline double msToMilliseconds(double ms)
    149 {
    150     double result = fmod(ms, msPerDay);
    151     if (result < 0)
    152         result += msPerDay;
    153     return result;
    154 }
    155 
    156 // 0: Sunday, 1: Monday, etc.
    157 static inline int msToWeekDay(double ms)
    158 {
    159     int wd = (static_cast<int>(msToDays(ms)) + 4) % 7;
    160     if (wd < 0)
    161         wd += 7;
    162     return wd;
    163 }
    164 
    165 static inline int msToSeconds(double ms)
    166 {
    167     double result = fmod(floor(ms / msPerSecond), secondsPerMinute);
    168     if (result < 0)
    169         result += secondsPerMinute;
    170     return static_cast<int>(result);
    171 }
    172 
    173 static inline int msToMinutes(double ms)
    174 {
    175     double result = fmod(floor(ms / msPerMinute), minutesPerHour);
    176     if (result < 0)
    177         result += minutesPerHour;
    178     return static_cast<int>(result);
    179 }
    180 
    181 static inline int msToHours(double ms)
    182 {
    183     double result = fmod(floor(ms/msPerHour), hoursPerDay);
    184     if (result < 0)
    185         result += hoursPerDay;
    186     return static_cast<int>(result);
    187 }
    188 
    189 static inline int monthFromDayInYear(int dayInYear, bool leapYear)
    190 {
    191     const int d = dayInYear;
    192     int step;
    193 
    194     if (d < (step = 31))
    195         return 0;
    196     step += (leapYear ? 29 : 28);
    197     if (d < step)
    198         return 1;
    199     if (d < (step += 31))
    200         return 2;
    201     if (d < (step += 30))
    202         return 3;
    203     if (d < (step += 31))
    204         return 4;
    205     if (d < (step += 30))
    206         return 5;
    207     if (d < (step += 31))
    208         return 6;
    209     if (d < (step += 31))
    210         return 7;
    211     if (d < (step += 30))
    212         return 8;
    213     if (d < (step += 31))
    214         return 9;
    215     if (d < (step += 30))
    216         return 10;
    217     return 11;
    218 }
    219 
    220 static inline bool checkMonth(int dayInYear, int& startDayOfThisMonth, int& startDayOfNextMonth, int daysInThisMonth)
    221 {
    222     startDayOfThisMonth = startDayOfNextMonth;
    223     startDayOfNextMonth += daysInThisMonth;
    224     return (dayInYear <= startDayOfNextMonth);
    225 }
    226 
    227 static inline int dayInMonthFromDayInYear(int dayInYear, bool leapYear)
    228 {
    229     const int d = dayInYear;
    230     int step;
    231     int next = 30;
    232 
    233     if (d <= next)
    234         return d + 1;
    235     const int daysInFeb = (leapYear ? 29 : 28);
    236     if (checkMonth(d, step, next, daysInFeb))
    237         return d - step;
    238     if (checkMonth(d, step, next, 31))
    239         return d - step;
    240     if (checkMonth(d, step, next, 30))
    241         return d - step;
    242     if (checkMonth(d, step, next, 31))
    243         return d - step;
    244     if (checkMonth(d, step, next, 30))
    245         return d - step;
    246     if (checkMonth(d, step, next, 31))
    247         return d - step;
    248     if (checkMonth(d, step, next, 31))
    249         return d - step;
    250     if (checkMonth(d, step, next, 30))
    251         return d - step;
    252     if (checkMonth(d, step, next, 31))
    253         return d - step;
    254     if (checkMonth(d, step, next, 30))
    255         return d - step;
    256     step = next;
    257     return d - step;
    258 }
    259 
    260 static inline int monthToDayInYear(int month, bool isLeapYear)
    261 {
    262     return firstDayOfMonth[isLeapYear][month];
    263 }
    264 
    265 static inline double timeToMS(double hour, double min, double sec, double ms)
    266 {
    267     return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms);
    268 }
    269 
    270 static int dateToDayInYear(int year, int month, int day)
    271 {
    272     year += month / 12;
    273 
    274     month %= 12;
    275     if (month < 0) {
    276         month += 12;
    277         --year;
    278     }
    279 
    280     int yearday = static_cast<int>(floor(daysFrom1970ToYear(year)));
    281     int monthday = monthToDayInYear(month, isLeapYear(year));
    282 
    283     return yearday + monthday + day - 1;
    284 }
    285 
    286 double getCurrentUTCTime()
    287 {
    288     return floor(getCurrentUTCTimeWithMicroseconds());
    289 }
    290 
    291 // Returns current time in milliseconds since 1 Jan 1970.
    292 double getCurrentUTCTimeWithMicroseconds()
    293 {
    294     return currentTime() * 1000.0;
    295 }
    296 
    297 void getLocalTime(const time_t* localTime, struct tm* localTM)
    298 {
    299 #if COMPILER(MSVC7) || COMPILER(MINGW) || PLATFORM(WIN_CE)
    300     *localTM = *localtime(localTime);
    301 #elif COMPILER(MSVC)
    302     localtime_s(localTM, localTime);
    303 #else
    304     localtime_r(localTime, localTM);
    305 #endif
    306 }
    307 
    308 // There is a hard limit at 2038 that we currently do not have a workaround
    309 // for (rdar://problem/5052975).
    310 static inline int maximumYearForDST()
    311 {
    312     return 2037;
    313 }
    314 
    315 static inline int minimumYearForDST()
    316 {
    317     // Because of the 2038 issue (see maximumYearForDST) if the current year is
    318     // greater than the max year minus 27 (2010), we want to use the max year
    319     // minus 27 instead, to ensure there is a range of 28 years that all years
    320     // can map to.
    321     return std::min(msToYear(getCurrentUTCTime()), maximumYearForDST() - 27) ;
    322 }
    323 
    324 /*
    325  * Find an equivalent year for the one given, where equivalence is deterined by
    326  * the two years having the same leapness and the first day of the year, falling
    327  * on the same day of the week.
    328  *
    329  * This function returns a year between this current year and 2037, however this
    330  * function will potentially return incorrect results if the current year is after
    331  * 2010, (rdar://problem/5052975), if the year passed in is before 1900 or after
    332  * 2100, (rdar://problem/5055038).
    333  */
    334 int equivalentYearForDST(int year)
    335 {
    336     // It is ok if the cached year is not the current year as long as the rules
    337     // for DST did not change between the two years; if they did the app would need
    338     // to be restarted.
    339     static int minYear = minimumYearForDST();
    340     int maxYear = maximumYearForDST();
    341 
    342     int difference;
    343     if (year > maxYear)
    344         difference = minYear - year;
    345     else if (year < minYear)
    346         difference = maxYear - year;
    347     else
    348         return year;
    349 
    350     int quotient = difference / 28;
    351     int product = (quotient) * 28;
    352 
    353     year += product;
    354     ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cast<int>(NaN)));
    355     return year;
    356 }
    357 
    358 static int32_t calculateUTCOffset()
    359 {
    360     tm localt;
    361     memset(&localt, 0, sizeof(localt));
    362  
    363     // get the difference between this time zone and UTC on Jan 01, 2000 12:00:00 AM
    364     localt.tm_mday = 1;
    365     localt.tm_year = 100;
    366     time_t utcOffset = 946684800 - mktime(&localt);
    367 
    368     return static_cast<int32_t>(utcOffset * 1000);
    369 }
    370 
    371 #if PLATFORM(DARWIN)
    372 static int32_t s_cachedUTCOffset; // In milliseconds. An assumption here is that access to an int32_t variable is atomic on platforms that take this code path.
    373 static bool s_haveCachedUTCOffset;
    374 static int s_notificationToken;
    375 #endif
    376 
    377 /*
    378  * Get the difference in milliseconds between this time zone and UTC (GMT)
    379  * NOT including DST.
    380  */
    381 double getUTCOffset()
    382 {
    383 #if PLATFORM(DARWIN)
    384     if (s_haveCachedUTCOffset) {
    385         int notified;
    386         uint32_t status = notify_check(s_notificationToken, &notified);
    387         if (status == NOTIFY_STATUS_OK && !notified)
    388             return s_cachedUTCOffset;
    389     }
    390 #endif
    391 
    392     int32_t utcOffset = calculateUTCOffset();
    393 
    394 #if PLATFORM(DARWIN)
    395     // Theoretically, it is possible that several threads will be executing this code at once, in which case we will have a race condition,
    396     // and a newer value may be overwritten. In practice, time zones don't change that often.
    397     s_cachedUTCOffset = utcOffset;
    398 #endif
    399 
    400     return utcOffset;
    401 }
    402 
    403 /*
    404  * Get the DST offset for the time passed in.  Takes
    405  * seconds (not milliseconds) and cannot handle dates before 1970
    406  * on some OS'
    407  */
    408 static double getDSTOffsetSimple(double localTimeSeconds, double utcOffset)
    409 {
    410     if (localTimeSeconds > maxUnixTime)
    411         localTimeSeconds = maxUnixTime;
    412     else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0)
    413         localTimeSeconds += secondsPerDay;
    414 
    415     //input is UTC so we have to shift back to local time to determine DST thus the + getUTCOffset()
    416     double offsetTime = (localTimeSeconds * msPerSecond) + utcOffset;
    417 
    418     // Offset from UTC but doesn't include DST obviously
    419     int offsetHour =  msToHours(offsetTime);
    420     int offsetMinute =  msToMinutes(offsetTime);
    421 
    422     // FIXME: time_t has a potential problem in 2038
    423     time_t localTime = static_cast<time_t>(localTimeSeconds);
    424 
    425     tm localTM;
    426     getLocalTime(&localTime, &localTM);
    427 
    428     double diff = ((localTM.tm_hour - offsetHour) * secondsPerHour) + ((localTM.tm_min - offsetMinute) * 60);
    429 
    430     if (diff < 0)
    431         diff += secondsPerDay;
    432 
    433     return (diff * msPerSecond);
    434 }
    435 
    436 // Get the DST offset, given a time in UTC
    437 static double getDSTOffset(double ms, double utcOffset)
    438 {
    439     // On Mac OS X, the call to localtime (see getDSTOffsetSimple) will return historically accurate
    440     // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript
    441     // standard explicitly dictates that historical information should not be considered when
    442     // determining DST. For this reason we shift away from years that localtime can handle but would
    443     // return historically accurate information.
    444     int year = msToYear(ms);
    445     int equivalentYear = equivalentYearForDST(year);
    446     if (year != equivalentYear) {
    447         bool leapYear = isLeapYear(year);
    448         int dayInYearLocal = dayInYear(ms, year);
    449         int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear);
    450         int month = monthFromDayInYear(dayInYearLocal, leapYear);
    451         int day = dateToDayInYear(equivalentYear, month, dayInMonth);
    452         ms = (day * msPerDay) + msToMilliseconds(ms);
    453     }
    454 
    455     return getDSTOffsetSimple(ms / msPerSecond, utcOffset);
    456 }
    457 
    458 double gregorianDateTimeToMS(const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
    459 {
    460     int day = dateToDayInYear(t.year + 1900, t.month, t.monthDay);
    461     double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds);
    462     double result = (day * msPerDay) + ms;
    463 
    464     if (!inputIsUTC) { // convert to UTC
    465         double utcOffset = getUTCOffset();
    466         result -= utcOffset;
    467         result -= getDSTOffset(result, utcOffset);
    468     }
    469 
    470     return result;
    471 }
    472 
    473 void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm)
    474 {
    475     // input is UTC
    476     double dstOff = 0.0;
    477     const double utcOff = getUTCOffset();
    478 
    479     if (!outputIsUTC) {  // convert to local time
    480         dstOff = getDSTOffset(ms, utcOff);
    481         ms += dstOff + utcOff;
    482     }
    483 
    484     const int year = msToYear(ms);
    485     tm.second   =  msToSeconds(ms);
    486     tm.minute   =  msToMinutes(ms);
    487     tm.hour     =  msToHours(ms);
    488     tm.weekDay  =  msToWeekDay(ms);
    489     tm.yearDay  =  dayInYear(ms, year);
    490     tm.monthDay =  dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year));
    491     tm.month    =  monthFromDayInYear(tm.yearDay, isLeapYear(year));
    492     tm.year     =  year - 1900;
    493     tm.isDST    =  dstOff != 0.0;
    494 
    495     tm.utcOffset = static_cast<long>((dstOff + utcOff) / msPerSecond);
    496     tm.timeZone = NULL;
    497 }
    498 
    499 void initDateMath()
    500 {
    501 #ifndef NDEBUG
    502     static bool alreadyInitialized;
    503     ASSERT(!alreadyInitialized++);
    504 #endif
    505 
    506     equivalentYearForDST(2000); // Need to call once to initialize a static used in this function.
    507 #if PLATFORM(DARWIN)
    508     // Register for a notification whenever the time zone changes.
    509     uint32_t status = notify_register_check("com.apple.system.timezone", &s_notificationToken);
    510     if (status == NOTIFY_STATUS_OK) {
    511         s_cachedUTCOffset = calculateUTCOffset();
    512         s_haveCachedUTCOffset = true;
    513     }
    514 #endif
    515 }
    516 
    517 static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, int second)
    518 {
    519     double days = (day - 32075)
    520         + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4)
    521         + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12
    522         - floor(3 * ((year + 4900.0 + (mon - 14) / 12) / 100) / 4)
    523         - 2440588;
    524     return ((days * hoursPerDay + hour) * minutesPerHour + minute) * secondsPerMinute + second;
    525 }
    526 
    527 // We follow the recommendation of RFC 2822 to consider all
    528 // obsolete time zones not listed here equivalent to "-0000".
    529 static const struct KnownZone {
    530 #if !PLATFORM(WIN_OS)
    531     const
    532 #endif
    533         char tzName[4];
    534     int tzOffset;
    535 } known_zones[] = {
    536     { "UT", 0 },
    537     { "GMT", 0 },
    538     { "EST", -300 },
    539     { "EDT", -240 },
    540     { "CST", -360 },
    541     { "CDT", -300 },
    542     { "MST", -420 },
    543     { "MDT", -360 },
    544     { "PST", -480 },
    545     { "PDT", -420 }
    546 };
    547 
    548 inline static void skipSpacesAndComments(const char*& s)
    549 {
    550     int nesting = 0;
    551     char ch;
    552     while ((ch = *s)) {
    553         if (!isASCIISpace(ch)) {
    554             if (ch == '(')
    555                 nesting++;
    556             else if (ch == ')' && nesting > 0)
    557                 nesting--;
    558             else if (nesting == 0)
    559                 break;
    560         }
    561         s++;
    562     }
    563 }
    564 
    565 // returns 0-11 (Jan-Dec); -1 on failure
    566 static int findMonth(const char* monthStr)
    567 {
    568     ASSERT(monthStr);
    569     char needle[4];
    570     for (int i = 0; i < 3; ++i) {
    571         if (!*monthStr)
    572             return -1;
    573         needle[i] = static_cast<char>(toASCIILower(*monthStr++));
    574     }
    575     needle[3] = '\0';
    576     const char *haystack = "janfebmaraprmayjunjulaugsepoctnovdec";
    577     const char *str = strstr(haystack, needle);
    578     if (str) {
    579         int position = static_cast<int>(str - haystack);
    580         if (position % 3 == 0)
    581             return position / 3;
    582     }
    583     return -1;
    584 }
    585 
    586 static bool parseLong(const char* string, char** stopPosition, int base, long* result)
    587 {
    588     *result = strtol(string, stopPosition, base);
    589     // Avoid the use of errno as it is not available on Windows CE
    590     if (string == *stopPosition || *result == LONG_MIN || *result == LONG_MAX)
    591         return false;
    592     return true;
    593 }
    594 
    59552double parseDate(const UString &date)
    59653{
    597     // This parses a date in the form:
    598     //     Tuesday, 09-Nov-99 23:12:40 GMT
    599     // or
    600     //     Sat, 01-Jan-2000 08:00:00 GMT
    601     // or
    602     //     Sat, 01 Jan 2000 08:00:00 GMT
    603     // or
    604     //     01 Jan 99 22:00 +0100    (exceptions in rfc822/rfc2822)
    605     // ### non RFC formats, added for Javascript:
    606     //     [Wednesday] January 09 1999 23:12:40 GMT
    607     //     [Wednesday] January 09 23:12:40 GMT 1999
    608     //
    609     // We ignore the weekday.
    610 
    611     CString dateCString = date.UTF8String();
    612     const char *dateString = dateCString.c_str();
    613      
    614     // Skip leading space
    615     skipSpacesAndComments(dateString);
    616 
    617     long month = -1;
    618     const char *wordStart = dateString;
    619     // Check contents of first words if not number
    620     while (*dateString && !isASCIIDigit(*dateString)) {
    621         if (isASCIISpace(*dateString) || *dateString == '(') {
    622             if (dateString - wordStart >= 3)
    623                 month = findMonth(wordStart);
    624             skipSpacesAndComments(dateString);
    625             wordStart = dateString;
    626         } else
    627            dateString++;
    628     }
    629 
    630     // Missing delimiter between month and day (like "January29")?
    631     if (month == -1 && wordStart != dateString)
    632         month = findMonth(wordStart);
    633 
    634     skipSpacesAndComments(dateString);
    635 
    636     if (!*dateString)
    637         return NaN;
    638 
    639     // ' 09-Nov-99 23:12:40 GMT'
    640     char* newPosStr;
    641     long day;
    642     if (!parseLong(dateString, &newPosStr, 10, &day))
    643         return NaN;
    644     dateString = newPosStr;
    645 
    646     if (!*dateString)
    647         return NaN;
    648 
    649     if (day < 0)
    650         return NaN;
    651 
    652     long year = 0;
    653     if (day > 31) {
    654         // ### where is the boundary and what happens below?
    655         if (*dateString != '/')
    656             return NaN;
    657         // looks like a YYYY/MM/DD date
    658         if (!*++dateString)
    659             return NaN;
    660         year = day;
    661         if (!parseLong(dateString, &newPosStr, 10, &month))
    662             return NaN;
    663         month -= 1;
    664         dateString = newPosStr;
    665         if (*dateString++ != '/' || !*dateString)
    666             return NaN;
    667         if (!parseLong(dateString, &newPosStr, 10, &day))
    668             return NaN;
    669         dateString = newPosStr;
    670     } else if (*dateString == '/' && month == -1) {
    671         dateString++;
    672         // This looks like a MM/DD/YYYY date, not an RFC date.
    673         month = day - 1; // 0-based
    674         if (!parseLong(dateString, &newPosStr, 10, &day))
    675             return NaN;
    676         if (day < 1 || day > 31)
    677             return NaN;
    678         dateString = newPosStr;
    679         if (*dateString == '/')
    680             dateString++;
    681         if (!*dateString)
    682             return NaN;
    683      } else {
    684         if (*dateString == '-')
    685             dateString++;
    686 
    687         skipSpacesAndComments(dateString);
    688 
    689         if (*dateString == ',')
    690             dateString++;
    691 
    692         if (month == -1) { // not found yet
    693             month = findMonth(dateString);
    694             if (month == -1)
    695                 return NaN;
    696 
    697             while (*dateString && *dateString != '-' && *dateString != ',' && !isASCIISpace(*dateString))
    698                 dateString++;
    699 
    700             if (!*dateString)
    701                 return NaN;
    702 
    703             // '-99 23:12:40 GMT'
    704             if (*dateString != '-' && *dateString != '/' && *dateString != ',' && !isASCIISpace(*dateString))
    705                 return NaN;
    706             dateString++;
    707         }
    708     }
    709 
    710     if (month < 0 || month > 11)
    711         return NaN;
    712 
    713     // '99 23:12:40 GMT'
    714     if (year <= 0 && *dateString) {
    715         if (!parseLong(dateString, &newPosStr, 10, &year))
    716             return NaN;
    717     }
    718    
    719     // Don't fail if the time is missing.
    720     long hour = 0;
    721     long minute = 0;
    722     long second = 0;
    723     if (!*newPosStr)
    724         dateString = newPosStr;
    725     else {
    726         // ' 23:12:40 GMT'
    727         if (!(isASCIISpace(*newPosStr) || *newPosStr == ',')) {
    728             if (*newPosStr != ':')
    729                 return NaN;
    730             // There was no year; the number was the hour.
    731             year = -1;
    732         } else {
    733             // in the normal case (we parsed the year), advance to the next number
    734             dateString = ++newPosStr;
    735             skipSpacesAndComments(dateString);
    736         }
    737 
    738         parseLong(dateString, &newPosStr, 10, &hour);
    739         // Do not check for errno here since we want to continue
    740         // even if errno was set becasue we are still looking
    741         // for the timezone!
    742 
    743         // Read a number? If not, this might be a timezone name.
    744         if (newPosStr != dateString) {
    745             dateString = newPosStr;
    746 
    747             if (hour < 0 || hour > 23)
    748                 return NaN;
    749 
    750             if (!*dateString)
    751                 return NaN;
    752 
    753             // ':12:40 GMT'
    754             if (*dateString++ != ':')
    755                 return NaN;
    756 
    757             if (!parseLong(dateString, &newPosStr, 10, &minute))
    758                 return NaN;
    759             dateString = newPosStr;
    760 
    761             if (minute < 0 || minute > 59)
    762                 return NaN;
    763 
    764             // ':40 GMT'
    765             if (*dateString && *dateString != ':' && !isASCIISpace(*dateString))
    766                 return NaN;
    767 
    768             // seconds are optional in rfc822 + rfc2822
    769             if (*dateString ==':') {
    770                 dateString++;
    771 
    772                 if (!parseLong(dateString, &newPosStr, 10, &second))
    773                     return NaN;
    774                 dateString = newPosStr;
    775            
    776                 if (second < 0 || second > 59)
    777                     return NaN;
    778             }
    779 
    780             skipSpacesAndComments(dateString);
    781 
    782             if (strncasecmp(dateString, "AM", 2) == 0) {
    783                 if (hour > 12)
    784                     return NaN;
    785                 if (hour == 12)
    786                     hour = 0;
    787                 dateString += 2;
    788                 skipSpacesAndComments(dateString);
    789             } else if (strncasecmp(dateString, "PM", 2) == 0) {
    790                 if (hour > 12)
    791                     return NaN;
    792                 if (hour != 12)
    793                     hour += 12;
    794                 dateString += 2;
    795                 skipSpacesAndComments(dateString);
    796             }
    797         }
    798     }
    799 
    800     bool haveTZ = false;
    801     int offset = 0;
    802 
    803     // Don't fail if the time zone is missing.
    804     // Some websites omit the time zone (4275206).
    805     if (*dateString) {
    806         if (strncasecmp(dateString, "GMT", 3) == 0 || strncasecmp(dateString, "UTC", 3) == 0) {
    807             dateString += 3;
    808             haveTZ = true;
    809         }
    810 
    811         if (*dateString == '+' || *dateString == '-') {
    812             long o;
    813             if (!parseLong(dateString, &newPosStr, 10, &o))
    814                 return NaN;
    815             dateString = newPosStr;
    816 
    817             if (o < -9959 || o > 9959)
    818                 return NaN;
    819 
    820             int sgn = (o < 0) ? -1 : 1;
    821             o = abs(o);
    822             if (*dateString != ':') {
    823                 offset = ((o / 100) * 60 + (o % 100)) * sgn;
    824             } else { // GMT+05:00
    825                 long o2;
    826                 if (!parseLong(dateString, &newPosStr, 10, &o2))
    827                     return NaN;
    828                 dateString = newPosStr;
    829                 offset = (o * 60 + o2) * sgn;
    830             }
    831             haveTZ = true;
    832         } else {
    833             for (int i = 0; i < int(sizeof(known_zones) / sizeof(KnownZone)); i++) {
    834                 if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) {
    835                     offset = known_zones[i].tzOffset;
    836                     dateString += strlen(known_zones[i].tzName);
    837                     haveTZ = true;
    838                     break;
    839                 }
    840             }
    841         }
    842     }
    843 
    844     skipSpacesAndComments(dateString);
    845 
    846     if (*dateString && year == -1) {
    847         if (!parseLong(dateString, &newPosStr, 10, &year))
    848             return NaN;
    849         dateString = newPosStr;
    850     }
    851      
    852     skipSpacesAndComments(dateString);
    853      
    854     // Trailing garbage
    855     if (*dateString)
    856         return NaN;
    857 
    858     // Y2K: Handle 2 digit years.
    859     if (year >= 0 && year < 100) {
    860         if (year < 50)
    861             year += 2000;
    862         else
    863             year += 1900;
    864     }
    865 
    866     // fall back to local timezone
    867     if (!haveTZ) {
    868         GregorianDateTime t;
    869         t.monthDay = day;
    870         t.month = month;
    871         t.year = year - 1900;
    872         t.isDST = -1;
    873         t.second = second;
    874         t.minute = minute;
    875         t.hour = hour;
    876 
    877         // Use our gregorianDateTimeToMS() rather than mktime() as the latter can't handle the full year range.
    878         return gregorianDateTimeToMS(t, 0, false);
    879     }
    880 
    881     return (ymdhmsToSeconds(year, month + 1, day, hour, minute, second) - (offset * 60.0)) * msPerSecond;
    882 }
    883 
    884 double timeClip(double t)
    885 {
    886     if (!isfinite(t))
    887         return NaN;
    888     if (fabs(t) > 8.64E15)
    889         return NaN;
    890     return trunc(t);
     54    return parseDateFromNullTerminatedCharacters(date.UTF8String().c_str());
    89155}
    89256
  • trunk/JavaScriptCore/runtime/DateConversion.h

    r44501 r44508  
    22 * Copyright (C) 1999-2000 Harri Porten ([email protected])
    33 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
     4 * Copyright (C) 2009 Google Inc. All rights reserved.
    45 *
    56 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
     
    3940 */
    4041
    41 #ifndef DateMath_h
    42 #define DateMath_h
     42#ifndef DateConversion_h
     43#define DateConversion_h
    4344
    44 #include <time.h>
    45 #include <string.h>
    46 #include <wtf/Noncopyable.h>
     45namespace WTF {
     46    struct GregorianDateTime;
     47}
    4748
    4849namespace JSC {
    4950
    5051class UString;
    51 struct GregorianDateTime;
    5252
    53 void initDateMath();
    54 void msToGregorianDateTime(double, bool outputIsUTC, GregorianDateTime&);
    55 double gregorianDateTimeToMS(const GregorianDateTime&, double, bool inputIsUTC);
    56 double getUTCOffset();
    57 int equivalentYearForDST(int year);
    58 double getCurrentUTCTime();
    59 double getCurrentUTCTimeWithMicroseconds();
    60 void getLocalTime(const time_t*, tm*);
    61 
    62 // Not really math related, but this is currently the only shared place to put these. 
    6353double parseDate(const UString&);
    64 double timeClip(double);
    65 UString formatDate(const GregorianDateTime&);
    66 UString formatDateUTCVariant(const GregorianDateTime&);
    67 UString formatTime(const GregorianDateTime&, bool inputIsUTC);
    68 
    69 
    70 const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
    71 const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
    72 
    73 const double hoursPerDay = 24.0;
    74 const double minutesPerHour = 60.0;
    75 const double secondsPerHour = 60.0 * 60.0;
    76 const double secondsPerMinute = 60.0;
    77 const double msPerSecond = 1000.0;
    78 const double msPerMinute = 60.0 * 1000.0;
    79 const double msPerHour = 60.0 * 60.0 * 1000.0;
    80 const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0;
    81 
    82 // Intentionally overridding the default tm of the system
    83 // Tee members of tm differ on various operating systems.
    84 struct GregorianDateTime : Noncopyable {
    85     GregorianDateTime()
    86         : second(0)
    87         , minute(0)
    88         , hour(0)
    89         , weekDay(0)
    90         , monthDay(0)
    91         , yearDay(0)
    92         , month(0)
    93         , year(0)
    94         , isDST(0)
    95         , utcOffset(0)
    96         , timeZone(0)
    97     {
    98     }
    99 
    100     ~GregorianDateTime()
    101     {
    102         delete [] timeZone;
    103     }
    104 
    105     GregorianDateTime(const tm& inTm)
    106         : second(inTm.tm_sec)
    107         , minute(inTm.tm_min)
    108         , hour(inTm.tm_hour)
    109         , weekDay(inTm.tm_wday)
    110         , monthDay(inTm.tm_mday)
    111         , yearDay(inTm.tm_yday)
    112         , month(inTm.tm_mon)
    113         , year(inTm.tm_year)
    114         , isDST(inTm.tm_isdst)
    115     {
    116 #if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !COMPILER(RVCT)
    117         utcOffset = static_cast<int>(inTm.tm_gmtoff);
    118 
    119         int inZoneSize = strlen(inTm.tm_zone) + 1;
    120         timeZone = new char[inZoneSize];
    121         strncpy(timeZone, inTm.tm_zone, inZoneSize);
    122 #else
    123         utcOffset = static_cast<int>(getUTCOffset() / msPerSecond + (isDST ? secondsPerHour : 0));
    124         timeZone = 0;
    125 #endif
    126     }
    127 
    128     operator tm() const
    129     {
    130         tm ret;
    131         memset(&ret, 0, sizeof(ret));
    132 
    133         ret.tm_sec   =  second;
    134         ret.tm_min   =  minute;
    135         ret.tm_hour  =  hour;
    136         ret.tm_wday  =  weekDay;
    137         ret.tm_mday  =  monthDay;
    138         ret.tm_yday  =  yearDay;
    139         ret.tm_mon   =  month;
    140         ret.tm_year  =  year;
    141         ret.tm_isdst =  isDST;
    142 
    143 #if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !COMPILER(RVCT)
    144         ret.tm_gmtoff = static_cast<long>(utcOffset);
    145         ret.tm_zone = timeZone;
    146 #endif
    147 
    148         return ret;
    149     }
    150 
    151     void copyFrom(const GregorianDateTime& rhs)
    152     {
    153         second = rhs.second;
    154         minute = rhs.minute;
    155         hour = rhs.hour;
    156         weekDay = rhs.weekDay;
    157         monthDay = rhs.monthDay;
    158         yearDay = rhs.yearDay;
    159         month = rhs.month;
    160         year = rhs.year;
    161         isDST = rhs.isDST;
    162         utcOffset = rhs.utcOffset;
    163         if (rhs.timeZone) {
    164             int inZoneSize = strlen(rhs.timeZone) + 1;
    165             timeZone = new char[inZoneSize];
    166             strncpy(timeZone, rhs.timeZone, inZoneSize);
    167         } else
    168             timeZone = 0;
    169     }
    170 
    171     int second;
    172     int minute;
    173     int hour;
    174     int weekDay;
    175     int monthDay;
    176     int yearDay;
    177     int month;
    178     int year;
    179     int isDST;
    180     int utcOffset;
    181     char* timeZone;
    182 };
    183 
    184 static inline int gmtoffset(const GregorianDateTime& t)
    185 {
    186     return t.utcOffset;
    187 }
     54UString formatDate(const WTF::GregorianDateTime&);
     55UString formatDateUTCVariant(const WTF::GregorianDateTime&);
     56UString formatTime(const WTF::GregorianDateTime&, bool inputIsUTC);
    18857
    18958} // namespace JSC
    19059
    191 #endif // DateMath_h
     60#endif // DateConversion_h
  • trunk/JavaScriptCore/runtime/DateInstance.cpp

    r38440 r44508  
    2323#include "DateInstance.h"
    2424
    25 #include "DateMath.h"
    2625#include <math.h>
     26#include <wtf/DateMath.h>
    2727#include <wtf/MathExtras.h>
    2828
     
    5959    if (outputIsUTC) {
    6060        if (m_cache->m_gregorianDateTimeUTCCachedForMS != milli) {
    61             JSC::msToGregorianDateTime(milli, true, m_cache->m_cachedGregorianDateTimeUTC);
     61            WTF::msToGregorianDateTime(milli, true, m_cache->m_cachedGregorianDateTimeUTC);
    6262            m_cache->m_gregorianDateTimeUTCCachedForMS = milli;
    6363        }
     
    6565    } else {
    6666        if (m_cache->m_gregorianDateTimeCachedForMS != milli) {
    67             JSC::msToGregorianDateTime(milli, false, m_cache->m_cachedGregorianDateTime);
     67            WTF::msToGregorianDateTime(milli, false, m_cache->m_cachedGregorianDateTime);
    6868            m_cache->m_gregorianDateTimeCachedForMS = milli;
    6969        }
  • trunk/JavaScriptCore/runtime/DateInstance.h

    r43122 r44508  
    2424#include "JSWrapperObject.h"
    2525
     26namespace WTF {
     27    struct GregorianDateTime;
     28}
     29
    2630namespace JSC {
    27 
    28     struct GregorianDateTime;
    2931
    3032    class DateInstance : public JSWrapperObject {
     
    3537        double internalNumber() const { return internalValue().uncheckedGetNumber(); }
    3638
    37         bool getTime(GregorianDateTime&, int& offset) const;
    38         bool getUTCTime(GregorianDateTime&) const;
     39        bool getTime(WTF::GregorianDateTime&, int& offset) const;
     40        bool getUTCTime(WTF::GregorianDateTime&) const;
    3941        bool getTime(double& milliseconds, int& offset) const;
    4042        bool getUTCTime(double& milliseconds) const;
     
    4244        static const ClassInfo info;
    4345
    44         void msToGregorianDateTime(double, bool outputIsUTC, GregorianDateTime&) const;
     46        void msToGregorianDateTime(double, bool outputIsUTC, WTF::GregorianDateTime&) const;
    4547
    4648    private:
  • trunk/JavaScriptCore/runtime/DatePrototype.cpp

    r43372 r44508  
    2323#include "DatePrototype.h"
    2424
    25 #include "DateMath.h"
     25#include "DateConversion.h"
    2626#include "Error.h"
    2727#include "JSString.h"
     
    3939#include <time.h>
    4040#include <wtf/Assertions.h>
     41#include <wtf/DateMath.h>
    4142#include <wtf/MathExtras.h>
    4243#include <wtf/StringExtras.h>
  • trunk/JavaScriptCore/runtime/InitializeThreading.cpp

    r44224 r44508  
    3232#include "JSImmediate.h"
    3333#include "Collector.h"
    34 #include "DateMath.h"
    3534#include "dtoa.h"
    3635#include "Identifier.h"
    3736#include "JSGlobalObject.h"
    3837#include "UString.h"
     38#include <wtf/DateMath.h>
    3939#include <wtf/Threading.h>
    4040
     
    5353#if ENABLE(JSC_MULTIPLE_THREADS)
    5454    s_dtoaP5Mutex = new Mutex;
    55     initDateMath();
     55    WTF::initializeDates();
    5656#endif
    5757}
  • trunk/JavaScriptCore/wtf/DateMath.cpp

    r44501 r44508  
    22 * Copyright (C) 1999-2000 Harri Porten ([email protected])
    33 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
    4  *
     4 * Copyright (C) 2009 Google Inc. All rights reserved.
     5 *
    56 * The Original Code is Mozilla Communicator client code, released
    67 * March 31, 1998.
     
    4344#include "DateMath.h"
    4445
    45 #include "JSNumberCell.h"
    46 #include <math.h>
     46#include "Assertions.h"
     47#include "ASCIICType.h"
     48#include "CurrentTime.h"
     49#include "MathExtras.h"
     50#include "StringExtras.h"
     51
     52#include <limits>
    4753#include <stdint.h>
    4854#include <time.h>
    49 #include <wtf/ASCIICType.h>
    50 #include <wtf/Assertions.h>
    51 #include <wtf/CurrentTime.h>
    52 #include <wtf/MathExtras.h>
    53 #include <wtf/StringExtras.h>
     55
    5456
    5557#if HAVE(ERRNO_H)
     
    6971#endif
    7072
    71 using namespace WTF;
    72 
    73 namespace JSC {
     73#define NaN std::numeric_limits<double>::quiet_NaN()
     74
     75namespace WTF {
    7476
    7577/* Constants */
     
    497499}
    498500
    499 void initDateMath()
     501void initializeDates()
    500502{
    501503#ifndef NDEBUG
     
    593595}
    594596
    595 double parseDate(const UString &date)
     597double parseDateFromNullTerminatedCharacters(const char* dateString)
    596598{
    597599    // This parses a date in the form:
     
    608610    //
    609611    // We ignore the weekday.
    610 
    611     CString dateCString = date.UTF8String();
    612     const char *dateString = dateCString.c_str();
    613612     
    614613    // Skip leading space
     
    716715            return NaN;
    717716    }
    718    
     717
    719718    // Don't fail if the time is missing.
    720719    long hour = 0;
     
    773772                    return NaN;
    774773                dateString = newPosStr;
    775            
     774
    776775                if (second < 0 || second > 59)
    777776                    return NaN;
     
    849848        dateString = newPosStr;
    850849    }
    851      
     850
    852851    skipSpacesAndComments(dateString);
    853      
     852
    854853    // Trailing garbage
    855854    if (*dateString)
     
    891890}
    892891
    893 UString formatDate(const GregorianDateTime &t)
    894 {
    895     char buffer[100];
    896     snprintf(buffer, sizeof(buffer), "%s %s %02d %04d",
    897         weekdayName[(t.weekDay + 6) % 7],
    898         monthName[t.month], t.monthDay, t.year + 1900);
    899     return buffer;
    900 }
    901 
    902 UString formatDateUTCVariant(const GregorianDateTime &t)
    903 {
    904     char buffer[100];
    905     snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d",
    906         weekdayName[(t.weekDay + 6) % 7],
    907         t.monthDay, monthName[t.month], t.year + 1900);
    908     return buffer;
    909 }
    910 
    911 UString formatTime(const GregorianDateTime &t, bool utc)
    912 {
    913     char buffer[100];
    914     if (utc) {
    915         snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
    916     } else {
    917         int offset = abs(gmtoffset(t));
    918         char timeZoneName[70];
    919         struct tm gtm = t;
    920         strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
    921 
    922         if (timeZoneName[0]) {
    923             snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",
    924                 t.hour, t.minute, t.second,
    925                 gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName);
    926         } else {
    927             snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",
    928                 t.hour, t.minute, t.second,
    929                 gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
    930         }
    931     }
    932     return UString(buffer);
    933 }
    934 
    935 } // namespace JSC
     892
     893} // namespace WTF
  • trunk/JavaScriptCore/wtf/DateMath.h

    r44501 r44508  
    22 * Copyright (C) 1999-2000 Harri Porten ([email protected])
    33 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
     4 * Copyright (C) 2009 Google Inc. All rights reserved.
    45 *
    56 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
     
    4647#include <wtf/Noncopyable.h>
    4748
    48 namespace JSC {
     49namespace WTF {
    4950
    50 class UString;
    5151struct GregorianDateTime;
    5252
    53 void initDateMath();
     53void initializeDates();
    5454void msToGregorianDateTime(double, bool outputIsUTC, GregorianDateTime&);
    5555double gregorianDateTimeToMS(const GregorianDateTime&, double, bool inputIsUTC);
     
    6161
    6262// Not really math related, but this is currently the only shared place to put these. 
    63 double parseDate(const UString&);
     63double parseDateFromNullTerminatedCharacters(const char*);
    6464double timeClip(double);
    65 UString formatDate(const GregorianDateTime&);
    66 UString formatDateUTCVariant(const GregorianDateTime&);
    67 UString formatTime(const GregorianDateTime&, bool inputIsUTC);
    68 
    6965
    7066const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
     
    187183}
    188184
    189 } // namespace JSC
     185} // namespace WTF
    190186
    191187#endif // DateMath_h
Note: See TracChangeset for help on using the changeset viewer.