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