| 1 | /* | 
| 2 |  * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) | 
| 3 |  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. | 
| 4 |  * Copyright (C) 2009 Google Inc. All rights reserved. | 
| 5 |  * | 
| 6 |  * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 
| 7 |  * | 
| 8 |  * The contents of this file are subject to the Mozilla Public License Version | 
| 9 |  * 1.1 (the "License"); you may not use this file except in compliance with | 
| 10 |  * the License. You may obtain a copy of the License at | 
| 11 |  * http://www.mozilla.org/MPL/ | 
| 12 |  * | 
| 13 |  * Software distributed under the License is distributed on an "AS IS" basis, | 
| 14 |  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | 
| 15 |  * for the specific language governing rights and limitations under the | 
| 16 |  * License. | 
| 17 |  * | 
| 18 |  * The Original Code is Mozilla Communicator client code, released | 
| 19 |  * March 31, 1998. | 
| 20 |  * | 
| 21 |  * The Initial Developer of the Original Code is | 
| 22 |  * Netscape Communications Corporation. | 
| 23 |  * Portions created by the Initial Developer are Copyright (C) 1998 | 
| 24 |  * the Initial Developer. All Rights Reserved. | 
| 25 |  * | 
| 26 |  * Contributor(s): | 
| 27 |  * | 
| 28 |  * Alternatively, the contents of this file may be used under the terms of | 
| 29 |  * either of the GNU General Public License Version 2 or later (the "GPL"), | 
| 30 |  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), | 
| 31 |  * in which case the provisions of the GPL or the LGPL are applicable instead | 
| 32 |  * of those above. If you wish to allow use of your version of this file only | 
| 33 |  * under the terms of either the GPL or the LGPL, and not to allow others to | 
| 34 |  * use your version of this file under the terms of the MPL, indicate your | 
| 35 |  * decision by deleting the provisions above and replace them with the notice | 
| 36 |  * and other provisions required by the GPL or the LGPL. If you do not delete | 
| 37 |  * the provisions above, a recipient may use your version of this file under | 
| 38 |  * the terms of any one of the MPL, the GPL or the LGPL. | 
| 39 |  * | 
| 40 |  */ | 
| 41 |  | 
| 42 | #ifndef DateMath_h | 
| 43 | #define DateMath_h | 
| 44 |  | 
| 45 | #include <math.h> | 
| 46 | #include <string.h> | 
| 47 | #include <time.h> | 
| 48 | #include <wtf/CurrentTime.h> | 
| 49 | #include <wtf/Noncopyable.h> | 
| 50 | #include <wtf/UnusedParam.h> | 
| 51 |  | 
| 52 | namespace WTF { | 
| 53 |  | 
| 54 | struct LocalTimeOffset { | 
| 55 |     LocalTimeOffset() | 
| 56 |         : isDST(false) | 
| 57 |         , offset(0) | 
| 58 |     { | 
| 59 |     } | 
| 60 |  | 
| 61 |     LocalTimeOffset(bool isDST, int offset) | 
| 62 |         : isDST(isDST) | 
| 63 |         , offset(offset) | 
| 64 |     { | 
| 65 |     } | 
| 66 |  | 
| 67 |     bool operator==(const LocalTimeOffset& other) | 
| 68 |     { | 
| 69 |         return isDST == other.isDST && offset == other.offset; | 
| 70 |     } | 
| 71 |  | 
| 72 |     bool operator!=(const LocalTimeOffset& other) | 
| 73 |     { | 
| 74 |         return isDST != other.isDST || offset != other.offset; | 
| 75 |     } | 
| 76 |  | 
| 77 |     bool isDST; | 
| 78 |     int offset; | 
| 79 | }; | 
| 80 |  | 
| 81 | void initializeDates(); | 
| 82 | int equivalentYearForDST(int year); | 
| 83 |  | 
| 84 | // Not really math related, but this is currently the only shared place to put these.   | 
| 85 | double parseDateFromNullTerminatedCharacters(const char* dateString); | 
| 86 | double timeClip(double); | 
| 87 |  | 
| 88 | inline double jsCurrentTime() | 
| 89 | { | 
| 90 |     // JavaScript doesn't recognize fractions of a millisecond. | 
| 91 |     return floor(WTF::currentTimeMS()); | 
| 92 | } | 
| 93 |  | 
| 94 | const char * const weekdayName[7] = { "Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" , "Sun"  }; | 
| 95 | const char * const monthName[12] = { "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec"  }; | 
| 96 |  | 
| 97 | const double hoursPerDay = 24.0; | 
| 98 | const double minutesPerHour = 60.0; | 
| 99 | const double secondsPerHour = 60.0 * 60.0; | 
| 100 | const double secondsPerMinute = 60.0; | 
| 101 | const double msPerSecond = 1000.0; | 
| 102 | const double msPerMinute = 60.0 * 1000.0; | 
| 103 | const double msPerHour = 60.0 * 60.0 * 1000.0; | 
| 104 | const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0; | 
| 105 | const double msPerMonth = 2592000000.0; | 
| 106 |  | 
| 107 | // Returns the number of days from 1970-01-01 to the specified date. | 
| 108 | double dateToDaysFrom1970(int year, int month, int day); | 
| 109 | int msToYear(double ms); | 
| 110 | int dayInYear(double ms, int year); | 
| 111 | int monthFromDayInYear(int dayInYear, bool leapYear); | 
| 112 | int dayInMonthFromDayInYear(int dayInYear, bool leapYear); | 
| 113 |  | 
| 114 | // Returns combined offset in millisecond (UTC + DST). | 
| 115 | LocalTimeOffset calculateLocalTimeOffset(double utcInMilliseconds); | 
| 116 |  | 
| 117 | } // namespace WTF | 
| 118 |  | 
| 119 | using WTF::dateToDaysFrom1970; | 
| 120 | using WTF::dayInMonthFromDayInYear; | 
| 121 | using WTF::dayInYear; | 
| 122 | using WTF::minutesPerHour; | 
| 123 | using WTF::monthFromDayInYear; | 
| 124 | using WTF::msPerDay; | 
| 125 | using WTF::msPerSecond; | 
| 126 | using WTF::msToYear; | 
| 127 | using WTF::secondsPerMinute; | 
| 128 | using WTF::LocalTimeOffset; | 
| 129 | using WTF::calculateLocalTimeOffset; | 
| 130 |  | 
| 131 | #if USE(JSC) | 
| 132 | namespace JSC { | 
| 133 | class ExecState; | 
| 134 | struct GregorianDateTime; | 
| 135 |  | 
| 136 | void msToGregorianDateTime(ExecState*, double, bool outputIsUTC, GregorianDateTime&); | 
| 137 | double gregorianDateTimeToMS(ExecState*, const GregorianDateTime&, double, bool inputIsUTC); | 
| 138 | double getUTCOffset(ExecState*); | 
| 139 | double parseDateFromNullTerminatedCharacters(ExecState*, const char* dateString); | 
| 140 |  | 
| 141 | // Intentionally overridding the default tm of the system. | 
| 142 | // The members of tm differ on various operating systems. | 
| 143 | struct GregorianDateTime : Noncopyable { | 
| 144 |     GregorianDateTime() | 
| 145 |         : second(0) | 
| 146 |         , minute(0) | 
| 147 |         , hour(0) | 
| 148 |         , weekDay(0) | 
| 149 |         , monthDay(0) | 
| 150 |         , yearDay(0) | 
| 151 |         , month(0) | 
| 152 |         , year(0) | 
| 153 |         , isDST(0) | 
| 154 |         , utcOffset(0) | 
| 155 |         , timeZone(0) | 
| 156 |     { | 
| 157 |     } | 
| 158 |  | 
| 159 |     ~GregorianDateTime() | 
| 160 |     { | 
| 161 |         delete [] timeZone; | 
| 162 |     } | 
| 163 |  | 
| 164 |     operator tm() const | 
| 165 |     { | 
| 166 |         tm ret; | 
| 167 |         memset(s: &ret, c: 0, n: sizeof(ret)); | 
| 168 |  | 
| 169 |         ret.tm_sec   =  second; | 
| 170 |         ret.tm_min   =  minute; | 
| 171 |         ret.tm_hour  =  hour; | 
| 172 |         ret.tm_wday  =  weekDay; | 
| 173 |         ret.tm_mday  =  monthDay; | 
| 174 |         ret.tm_yday  =  yearDay; | 
| 175 |         ret.tm_mon   =  month; | 
| 176 |         ret.tm_year  =  year; | 
| 177 |         ret.tm_isdst =  isDST; | 
| 178 |  | 
| 179 | #if HAVE(TM_GMTOFF) | 
| 180 |         ret.tm_gmtoff = static_cast<long>(utcOffset); | 
| 181 | #endif | 
| 182 | #if HAVE(TM_ZONE) | 
| 183 |         ret.tm_zone = timeZone; | 
| 184 | #endif | 
| 185 |  | 
| 186 |         return ret; | 
| 187 |     } | 
| 188 |  | 
| 189 |     void copyFrom(const GregorianDateTime& rhs) | 
| 190 |     { | 
| 191 |         second = rhs.second; | 
| 192 |         minute = rhs.minute; | 
| 193 |         hour = rhs.hour; | 
| 194 |         weekDay = rhs.weekDay; | 
| 195 |         monthDay = rhs.monthDay; | 
| 196 |         yearDay = rhs.yearDay; | 
| 197 |         month = rhs.month; | 
| 198 |         year = rhs.year; | 
| 199 |         isDST = rhs.isDST; | 
| 200 |         utcOffset = rhs.utcOffset; | 
| 201 |         if (rhs.timeZone) { | 
| 202 |             int inZoneSize = strlen(s: rhs.timeZone) + 1; | 
| 203 |             timeZone = new char[inZoneSize]; | 
| 204 |             strncpy(dest: timeZone, src: rhs.timeZone, n: inZoneSize); | 
| 205 |         } else | 
| 206 |             timeZone = 0; | 
| 207 |     } | 
| 208 |  | 
| 209 |     int second; | 
| 210 |     int minute; | 
| 211 |     int hour; | 
| 212 |     int weekDay; | 
| 213 |     int monthDay; | 
| 214 |     int yearDay; | 
| 215 |     int month; | 
| 216 |     int year; | 
| 217 |     int isDST; | 
| 218 |     int utcOffset; | 
| 219 |     char* timeZone; | 
| 220 | }; | 
| 221 |  | 
| 222 | static inline int gmtoffset(const GregorianDateTime& t) | 
| 223 | { | 
| 224 |     return t.utcOffset; | 
| 225 | } | 
| 226 | } // namespace JSC | 
| 227 | #endif // USE(JSC) | 
| 228 |  | 
| 229 | #endif // DateMath_h | 
| 230 |  |