Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: third_party/WebKit/Source/wtf/DateMath.cpp

Issue 1436153002: Apply clang-format with Chromium-style without column limit. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/wtf/DateMath.h ('k') | third_party/WebKit/Source/wtf/Deque.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 3 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4 * Copyright (C) 2009 Google Inc. All rights reserved. 4 * Copyright (C) 2009 Google Inc. All rights reserved.
5 * Copyright (C) 2007-2009 Torch Mobile, Inc. 5 * Copyright (C) 2007-2009 Torch Mobile, Inc.
6 * Copyright (C) 2010 &yet, LLC. (nate@andyet.net) 6 * Copyright (C) 2010 &yet, LLC. (nate@andyet.net)
7 * 7 *
8 * The Original Code is Mozilla Communicator client code, released 8 * The Original Code is Mozilla Communicator client code, released
9 * March 31, 1998. 9 * March 31, 1998.
10 * 10 *
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 #include <sys/time.h> 92 #include <sys/time.h>
93 #endif 93 #endif
94 94
95 namespace WTF { 95 namespace WTF {
96 96
97 /* Constants */ 97 /* Constants */
98 98
99 static const double hoursPerDay = 24.0; 99 static const double hoursPerDay = 24.0;
100 static const double secondsPerDay = 24.0 * 60.0 * 60.0; 100 static const double secondsPerDay = 24.0 * 60.0 * 60.0;
101 101
102 static const double maxUnixTime = 2145859200.0; // 12/31/2037 102 static const double maxUnixTime = 2145859200.0; // 12/31/2037
103 103
104 // Day of year for the first day of each month, where index 0 is January, and da y 0 is January 1. 104 // Day of year for the first day of each month, where index 0 is January, and da y 0 is January 1.
105 // First for non-leap years, then for leap years. 105 // First for non-leap years, then for leap years.
106 static const int firstDayOfMonth[2][12] = { 106 static const int firstDayOfMonth[2][12] = {
107 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, 107 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
108 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} 108 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}};
109 };
110 109
111 static inline void getLocalTime(const time_t* localTime, struct tm* localTM) 110 static inline void getLocalTime(const time_t* localTime, struct tm* localTM) {
112 {
113 #if COMPILER(MSVC) 111 #if COMPILER(MSVC)
114 localtime_s(localTM, localTime); 112 localtime_s(localTM, localTime);
115 #else 113 #else
116 localtime_r(localTime, localTM); 114 localtime_r(localTime, localTM);
117 #endif 115 #endif
118 } 116 }
119 117
120 bool isLeapYear(int year) 118 bool isLeapYear(int year) {
121 { 119 if (year % 4 != 0)
122 if (year % 4 != 0) 120 return false;
123 return false; 121 if (year % 400 == 0)
124 if (year % 400 == 0)
125 return true;
126 if (year % 100 == 0)
127 return false;
128 return true; 122 return true;
123 if (year % 100 == 0)
124 return false;
125 return true;
129 } 126 }
130 127
131 static inline int daysInYear(int year) 128 static inline int daysInYear(int year) {
132 { 129 return 365 + isLeapYear(year);
133 return 365 + isLeapYear(year);
134 } 130 }
135 131
136 static inline double daysFrom1970ToYear(int year) 132 static inline double daysFrom1970ToYear(int year) {
137 { 133 // The Gregorian Calendar rules for leap years:
138 // The Gregorian Calendar rules for leap years: 134 // Every fourth year is a leap year. 2004, 2008, and 2012 are leap years.
139 // Every fourth year is a leap year. 2004, 2008, and 2012 are leap years. 135 // However, every hundredth year is not a leap year. 1900 and 2100 are not le ap years.
140 // However, every hundredth year is not a leap year. 1900 and 2100 are not leap years. 136 // Every four hundred years, there's a leap year after all. 2000 and 2400 are leap years.
141 // Every four hundred years, there's a leap year after all. 2000 and 2400 a re leap years.
142 137
143 static const int leapDaysBefore1971By4Rule = 1970 / 4; 138 static const int leapDaysBefore1971By4Rule = 1970 / 4;
144 static const int excludedLeapDaysBefore1971By100Rule = 1970 / 100; 139 static const int excludedLeapDaysBefore1971By100Rule = 1970 / 100;
145 static const int leapDaysBefore1971By400Rule = 1970 / 400; 140 static const int leapDaysBefore1971By400Rule = 1970 / 400;
146 141
147 const double yearMinusOne = year - 1; 142 const double yearMinusOne = year - 1;
148 const double yearsToAddBy4Rule = floor(yearMinusOne / 4.0) - leapDaysBefore1 971By4Rule; 143 const double yearsToAddBy4Rule = floor(yearMinusOne / 4.0) - leapDaysBefore197 1By4Rule;
149 const double yearsToExcludeBy100Rule = floor(yearMinusOne / 100.0) - exclude dLeapDaysBefore1971By100Rule; 144 const double yearsToExcludeBy100Rule = floor(yearMinusOne / 100.0) - excludedL eapDaysBefore1971By100Rule;
150 const double yearsToAddBy400Rule = floor(yearMinusOne / 400.0) - leapDaysBef ore1971By400Rule; 145 const double yearsToAddBy400Rule = floor(yearMinusOne / 400.0) - leapDaysBefor e1971By400Rule;
151 146
152 return 365.0 * (year - 1970) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule; 147 return 365.0 * (year - 1970) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + y earsToAddBy400Rule;
153 } 148 }
154 149
155 static double msToDays(double ms) 150 static double msToDays(double ms) {
156 { 151 return floor(ms / msPerDay);
157 return floor(ms / msPerDay);
158 } 152 }
159 153
160 static void appendTwoDigitNumber(StringBuilder& builder, int number) 154 static void appendTwoDigitNumber(StringBuilder& builder, int number) {
161 { 155 ASSERT(number >= 0 && number < 100);
162 ASSERT(number >= 0 && number < 100); 156 if (number <= 9)
163 if (number <= 9) 157 builder.append('0');
164 builder.append('0'); 158 builder.appendNumber(number);
165 builder.appendNumber(number);
166 } 159 }
167 160
168 int msToYear(double ms) 161 int msToYear(double ms) {
169 { 162 int approxYear = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970);
170 int approxYear = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970); 163 double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear);
171 double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear); 164 if (msFromApproxYearTo1970 > ms)
172 if (msFromApproxYearTo1970 > ms) 165 return approxYear - 1;
173 return approxYear - 1; 166 if (msFromApproxYearTo1970 + msPerDay * daysInYear(approxYear) <= ms)
174 if (msFromApproxYearTo1970 + msPerDay * daysInYear(approxYear) <= ms) 167 return approxYear + 1;
175 return approxYear + 1; 168 return approxYear;
176 return approxYear;
177 } 169 }
178 170
179 int dayInYear(double ms, int year) 171 int dayInYear(double ms, int year) {
180 { 172 return static_cast<int>(msToDays(ms) - daysFrom1970ToYear(year));
181 return static_cast<int>(msToDays(ms) - daysFrom1970ToYear(year));
182 } 173 }
183 174
184 static inline double msToMilliseconds(double ms) 175 static inline double msToMilliseconds(double ms) {
185 { 176 double result = fmod(ms, msPerDay);
186 double result = fmod(ms, msPerDay); 177 if (result < 0)
187 if (result < 0) 178 result += msPerDay;
188 result += msPerDay; 179 return result;
189 return result;
190 } 180 }
191 181
192 int monthFromDayInYear(int dayInYear, bool leapYear) 182 int monthFromDayInYear(int dayInYear, bool leapYear) {
193 { 183 const int d = dayInYear;
194 const int d = dayInYear; 184 int step;
195 int step;
196 185
197 if (d < (step = 31)) 186 if (d < (step = 31))
198 return 0; 187 return 0;
199 step += (leapYear ? 29 : 28); 188 step += (leapYear ? 29 : 28);
200 if (d < step) 189 if (d < step)
201 return 1; 190 return 1;
202 if (d < (step += 31)) 191 if (d < (step += 31))
203 return 2; 192 return 2;
204 if (d < (step += 30)) 193 if (d < (step += 30))
205 return 3; 194 return 3;
206 if (d < (step += 31)) 195 if (d < (step += 31))
207 return 4; 196 return 4;
208 if (d < (step += 30)) 197 if (d < (step += 30))
209 return 5; 198 return 5;
210 if (d < (step += 31)) 199 if (d < (step += 31))
211 return 6; 200 return 6;
212 if (d < (step += 31)) 201 if (d < (step += 31))
213 return 7; 202 return 7;
214 if (d < (step += 30)) 203 if (d < (step += 30))
215 return 8; 204 return 8;
216 if (d < (step += 31)) 205 if (d < (step += 31))
217 return 9; 206 return 9;
218 if (d < (step += 30)) 207 if (d < (step += 30))
219 return 10; 208 return 10;
220 return 11; 209 return 11;
221 } 210 }
222 211
223 static inline bool checkMonth(int dayInYear, int& startDayOfThisMonth, int& star tDayOfNextMonth, int daysInThisMonth) 212 static inline bool checkMonth(int dayInYear, int& startDayOfThisMonth, int& star tDayOfNextMonth, int daysInThisMonth) {
224 { 213 startDayOfThisMonth = startDayOfNextMonth;
225 startDayOfThisMonth = startDayOfNextMonth; 214 startDayOfNextMonth += daysInThisMonth;
226 startDayOfNextMonth += daysInThisMonth; 215 return (dayInYear <= startDayOfNextMonth);
227 return (dayInYear <= startDayOfNextMonth);
228 } 216 }
229 217
230 int dayInMonthFromDayInYear(int dayInYear, bool leapYear) 218 int dayInMonthFromDayInYear(int dayInYear, bool leapYear) {
231 { 219 const int d = dayInYear;
232 const int d = dayInYear; 220 int step;
233 int step; 221 int next = 30;
234 int next = 30;
235 222
236 if (d <= next) 223 if (d <= next)
237 return d + 1; 224 return d + 1;
238 const int daysInFeb = (leapYear ? 29 : 28); 225 const int daysInFeb = (leapYear ? 29 : 28);
239 if (checkMonth(d, step, next, daysInFeb)) 226 if (checkMonth(d, step, next, daysInFeb))
240 return d - step;
241 if (checkMonth(d, step, next, 31))
242 return d - step;
243 if (checkMonth(d, step, next, 30))
244 return d - step;
245 if (checkMonth(d, step, next, 31))
246 return d - step;
247 if (checkMonth(d, step, next, 30))
248 return d - step;
249 if (checkMonth(d, step, next, 31))
250 return d - step;
251 if (checkMonth(d, step, next, 31))
252 return d - step;
253 if (checkMonth(d, step, next, 30))
254 return d - step;
255 if (checkMonth(d, step, next, 31))
256 return d - step;
257 if (checkMonth(d, step, next, 30))
258 return d - step;
259 step = next;
260 return d - step; 227 return d - step;
228 if (checkMonth(d, step, next, 31))
229 return d - step;
230 if (checkMonth(d, step, next, 30))
231 return d - step;
232 if (checkMonth(d, step, next, 31))
233 return d - step;
234 if (checkMonth(d, step, next, 30))
235 return d - step;
236 if (checkMonth(d, step, next, 31))
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 step = next;
247 return d - step;
261 } 248 }
262 249
263 int dayInYear(int year, int month, int day) 250 int dayInYear(int year, int month, int day) {
264 { 251 return firstDayOfMonth[isLeapYear(year)][month] + day - 1;
265 return firstDayOfMonth[isLeapYear(year)][month] + day - 1;
266 } 252 }
267 253
268 double dateToDaysFrom1970(int year, int month, int day) 254 double dateToDaysFrom1970(int year, int month, int day) {
269 { 255 year += month / 12;
270 year += month / 12;
271 256
272 month %= 12; 257 month %= 12;
273 if (month < 0) { 258 if (month < 0) {
274 month += 12; 259 month += 12;
275 --year; 260 --year;
276 } 261 }
277 262
278 double yearday = floor(daysFrom1970ToYear(year)); 263 double yearday = floor(daysFrom1970ToYear(year));
279 ASSERT((year >= 1970 && yearday >= 0) || (year < 1970 && yearday < 0)); 264 ASSERT((year >= 1970 && yearday >= 0) || (year < 1970 && yearday < 0));
280 return yearday + dayInYear(year, month, day); 265 return yearday + dayInYear(year, month, day);
281 } 266 }
282 267
283 // There is a hard limit at 2038 that we currently do not have a workaround 268 // There is a hard limit at 2038 that we currently do not have a workaround
284 // for (rdar://problem/5052975). 269 // for (rdar://problem/5052975).
285 static inline int maximumYearForDST() 270 static inline int maximumYearForDST() {
286 { 271 return 2037;
287 return 2037;
288 } 272 }
289 273
290 static inline double jsCurrentTime() 274 static inline double jsCurrentTime() {
291 { 275 // JavaScript doesn't recognize fractions of a millisecond.
292 // JavaScript doesn't recognize fractions of a millisecond. 276 return floor(WTF::currentTimeMS());
293 return floor(WTF::currentTimeMS());
294 } 277 }
295 278
296 static inline int minimumYearForDST() 279 static inline int minimumYearForDST() {
297 { 280 // Because of the 2038 issue (see maximumYearForDST) if the current year is
298 // Because of the 2038 issue (see maximumYearForDST) if the current year is 281 // greater than the max year minus 27 (2010), we want to use the max year
299 // greater than the max year minus 27 (2010), we want to use the max year 282 // minus 27 instead, to ensure there is a range of 28 years that all years
300 // minus 27 instead, to ensure there is a range of 28 years that all years 283 // can map to.
301 // can map to. 284 return std::min(msToYear(jsCurrentTime()), maximumYearForDST() - 27);
302 return std::min(msToYear(jsCurrentTime()), maximumYearForDST() - 27);
303 } 285 }
304 286
305 /* 287 /*
306 * Find an equivalent year for the one given, where equivalence is deterined by 288 * Find an equivalent year for the one given, where equivalence is deterined by
307 * the two years having the same leapness and the first day of the year, falling 289 * the two years having the same leapness and the first day of the year, falling
308 * on the same day of the week. 290 * on the same day of the week.
309 * 291 *
310 * This function returns a year between this current year and 2037, however this 292 * This function returns a year between this current year and 2037, however this
311 * function will potentially return incorrect results if the current year is aft er 293 * function will potentially return incorrect results if the current year is aft er
312 * 2010, (rdar://problem/5052975), if the year passed in is before 1900 or after 294 * 2010, (rdar://problem/5052975), if the year passed in is before 1900 or after
313 * 2100, (rdar://problem/5055038). 295 * 2100, (rdar://problem/5055038).
314 */ 296 */
315 static int equivalentYearForDST(int year) 297 static int equivalentYearForDST(int year) {
316 { 298 // It is ok if the cached year is not the current year as long as the rules
317 // It is ok if the cached year is not the current year as long as the rules 299 // for DST did not change between the two years; if they did the app would nee d
318 // for DST did not change between the two years; if they did the app would n eed 300 // to be restarted.
319 // to be restarted. 301 static int minYear = minimumYearForDST();
320 static int minYear = minimumYearForDST(); 302 int maxYear = maximumYearForDST();
321 int maxYear = maximumYearForDST(); 303
322 304 int difference;
323 int difference; 305 if (year > maxYear)
324 if (year > maxYear) 306 difference = minYear - year;
325 difference = minYear - year; 307 else if (year < minYear)
326 else if (year < minYear) 308 difference = maxYear - year;
327 difference = maxYear - year; 309 else
328 else
329 return year;
330
331 int quotient = difference / 28;
332 int product = (quotient) * 28;
333
334 year += product;
335 ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cas t<int>(std::numeric_limits<double>::quiet_NaN())));
336 return year; 310 return year;
337 } 311
338 312 int quotient = difference / 28;
339 static double calculateUTCOffset() 313 int product = (quotient)*28;
340 { 314
315 year += product;
316 ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cast< int>(std::numeric_limits<double>::quiet_NaN())));
317 return year;
318 }
319
320 static double calculateUTCOffset() {
341 #if OS(WIN) 321 #if OS(WIN)
342 TIME_ZONE_INFORMATION timeZoneInformation; 322 TIME_ZONE_INFORMATION timeZoneInformation;
343 GetTimeZoneInformation(&timeZoneInformation); 323 GetTimeZoneInformation(&timeZoneInformation);
344 int32_t bias = timeZoneInformation.Bias + timeZoneInformation.StandardBias; 324 int32_t bias = timeZoneInformation.Bias + timeZoneInformation.StandardBias;
345 return -bias * 60 * 1000; 325 return -bias * 60 * 1000;
346 #else 326 #else
347 time_t localTime = time(0); 327 time_t localTime = time(0);
348 tm localt; 328 tm localt;
349 getLocalTime(&localTime, &localt); 329 getLocalTime(&localTime, &localt);
350 330
351 // tm_gmtoff includes any daylight savings offset, so subtract it. 331 // tm_gmtoff includes any daylight savings offset, so subtract it.
352 return static_cast<double>(localt.tm_gmtoff * msPerSecond - (localt.tm_isdst > 0 ? msPerHour : 0)); 332 return static_cast<double>(localt.tm_gmtoff * msPerSecond - (localt.tm_isdst > 0 ? msPerHour : 0));
353 #endif 333 #endif
354 } 334 }
355 335
356 /* 336 /*
357 * Get the DST offset for the time passed in. 337 * Get the DST offset for the time passed in.
358 */ 338 */
359 static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset ) 339 static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset ) {
360 { 340 if (localTimeSeconds > maxUnixTime)
361 if (localTimeSeconds > maxUnixTime) 341 localTimeSeconds = maxUnixTime;
362 localTimeSeconds = maxUnixTime; 342 else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0)
363 else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (doe s not work with 0) 343 localTimeSeconds += secondsPerDay;
364 localTimeSeconds += secondsPerDay; 344
365 345 // FIXME: time_t has a potential problem in 2038
366 // FIXME: time_t has a potential problem in 2038 346 time_t localTime = static_cast<time_t>(localTimeSeconds);
367 time_t localTime = static_cast<time_t>(localTimeSeconds); 347
368 348 tm localTM;
369 tm localTM; 349 getLocalTime(&localTime, &localTM);
370 getLocalTime(&localTime, &localTM); 350
371 351 return localTM.tm_isdst > 0 ? msPerHour : 0;
372 return localTM.tm_isdst > 0 ? msPerHour : 0;
373 } 352 }
374 353
375 // Get the DST offset, given a time in UTC 354 // Get the DST offset, given a time in UTC
376 static double calculateDSTOffset(double ms, double utcOffset) 355 static double calculateDSTOffset(double ms, double utcOffset) {
377 { 356 // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will retu rn historically accurate
378 // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will re turn historically accurate 357 // DST information (e.g. New Zealand did not have DST from 1946 to 1974) howev er the JavaScript
379 // DST information (e.g. New Zealand did not have DST from 1946 to 1974) how ever the JavaScript 358 // standard explicitly dictates that historical information should not be cons idered when
380 // standard explicitly dictates that historical information should not be co nsidered when 359 // determining DST. For this reason we shift away from years that localtime ca n handle but would
381 // determining DST. For this reason we shift away from years that localtime can handle but would 360 // return historically accurate information.
382 // return historically accurate information. 361 int year = msToYear(ms);
383 int year = msToYear(ms); 362 int equivalentYear = equivalentYearForDST(year);
384 int equivalentYear = equivalentYearForDST(year); 363 if (year != equivalentYear) {
385 if (year != equivalentYear) { 364 bool leapYear = isLeapYear(year);
386 bool leapYear = isLeapYear(year); 365 int dayInYearLocal = dayInYear(ms, year);
387 int dayInYearLocal = dayInYear(ms, year); 366 int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear);
388 int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear); 367 int month = monthFromDayInYear(dayInYearLocal, leapYear);
389 int month = monthFromDayInYear(dayInYearLocal, leapYear); 368 double day = dateToDaysFrom1970(equivalentYear, month, dayInMonth);
390 double day = dateToDaysFrom1970(equivalentYear, month, dayInMonth); 369 ms = (day * msPerDay) + msToMilliseconds(ms);
391 ms = (day * msPerDay) + msToMilliseconds(ms); 370 }
392 } 371
393 372 return calculateDSTOffsetSimple(ms / msPerSecond, utcOffset);
394 return calculateDSTOffsetSimple(ms / msPerSecond, utcOffset); 373 }
395 } 374
396 375 void initializeDates() {
397 void initializeDates()
398 {
399 #if ENABLE(ASSERT) 376 #if ENABLE(ASSERT)
400 static bool alreadyInitialized; 377 static bool alreadyInitialized;
401 ASSERT(!alreadyInitialized); 378 ASSERT(!alreadyInitialized);
402 alreadyInitialized = true; 379 alreadyInitialized = true;
403 #endif 380 #endif
404 381
405 equivalentYearForDST(2000); // Need to call once to initialize a static used in this function. 382 equivalentYearForDST(2000); // Need to call once to initialize a static used in this function.
406 } 383 }
407 384
408 static inline double ymdhmsToSeconds(int year, long mon, long day, long hour, lo ng minute, double second) 385 static inline double ymdhmsToSeconds(int year, long mon, long day, long hour, lo ng minute, double second) {
409 { 386 double days = (day - 32075) + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4) + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12 - floor(3 * ((year + 4900.0 + (mon - 14) / 12) / 100) / 4) - 2440588;
410 double days = (day - 32075) 387 return ((days * hoursPerDay + hour) * minutesPerHour + minute) * secondsPerMin ute + second;
411 + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4)
412 + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12
413 - floor(3 * ((year + 4900.0 + (mon - 14) / 12) / 100) / 4)
414 - 2440588;
415 return ((days * hoursPerDay + hour) * minutesPerHour + minute) * secondsPerM inute + second;
416 } 388 }
417 389
418 // We follow the recommendation of RFC 2822 to consider all 390 // We follow the recommendation of RFC 2822 to consider all
419 // obsolete time zones not listed here equivalent to "-0000". 391 // obsolete time zones not listed here equivalent to "-0000".
420 static const struct KnownZone { 392 static const struct KnownZone {
421 #if !OS(WIN) 393 #if !OS(WIN)
422 const 394 const
423 #endif 395 #endif
424 char tzName[4]; 396 char tzName[4];
425 int tzOffset; 397 int tzOffset;
426 } known_zones[] = { 398 } known_zones[] = {
427 { "UT", 0 }, 399 {"UT", 0},
428 { "GMT", 0 }, 400 {"GMT", 0},
429 { "EST", -300 }, 401 {"EST", -300},
430 { "EDT", -240 }, 402 {"EDT", -240},
431 { "CST", -360 }, 403 {"CST", -360},
432 { "CDT", -300 }, 404 {"CDT", -300},
433 { "MST", -420 }, 405 {"MST", -420},
434 { "MDT", -360 }, 406 {"MDT", -360},
435 { "PST", -480 }, 407 {"PST", -480},
436 { "PDT", -420 } 408 {"PDT", -420}};
437 }; 409
438 410 inline static void skipSpacesAndComments(const char*& s) {
439 inline static void skipSpacesAndComments(const char*& s) 411 int nesting = 0;
440 { 412 char ch;
441 int nesting = 0; 413 while ((ch = *s)) {
442 char ch; 414 if (!isASCIISpace(ch)) {
443 while ((ch = *s)) { 415 if (ch == '(')
444 if (!isASCIISpace(ch)) { 416 nesting++;
445 if (ch == '(') 417 else if (ch == ')' && nesting > 0)
446 nesting++; 418 nesting--;
447 else if (ch == ')' && nesting > 0) 419 else if (nesting == 0)
448 nesting--; 420 break;
449 else if (nesting == 0) 421 }
450 break; 422 s++;
423 }
424 }
425
426 // returns 0-11 (Jan-Dec); -1 on failure
427 static int findMonth(const char* monthStr) {
428 ASSERT(monthStr);
429 char needle[4];
430 for (int i = 0; i < 3; ++i) {
431 if (!*monthStr)
432 return -1;
433 needle[i] = static_cast<char>(toASCIILower(*monthStr++));
434 }
435 needle[3] = '\0';
436 const char* haystack = "janfebmaraprmayjunjulaugsepoctnovdec";
437 const char* str = strstr(haystack, needle);
438 if (str) {
439 int position = static_cast<int>(str - haystack);
440 if (position % 3 == 0)
441 return position / 3;
442 }
443 return -1;
444 }
445
446 static bool parseInt(const char* string, char** stopPosition, int base, int* res ult) {
447 long longResult = strtol(string, stopPosition, base);
448 // Avoid the use of errno as it is not available on Windows CE
449 if (string == *stopPosition || longResult <= std::numeric_limits<int>::min() | | longResult >= std::numeric_limits<int>::max())
450 return false;
451 *result = static_cast<int>(longResult);
452 return true;
453 }
454
455 static bool parseLong(const char* string, char** stopPosition, int base, long* r esult) {
456 *result = strtol(string, stopPosition, base);
457 // Avoid the use of errno as it is not available on Windows CE
458 if (string == *stopPosition || *result == std::numeric_limits<long>::min() || *result == std::numeric_limits<long>::max())
459 return false;
460 return true;
461 }
462
463 // Odd case where 'exec' is allowed to be 0, to accomodate a caller in WebCore.
464 static double parseDateFromNullTerminatedCharacters(const char* dateString, bool & haveTZ, int& offset) {
465 haveTZ = false;
466 offset = 0;
467
468 // This parses a date in the form:
469 // Tuesday, 09-Nov-99 23:12:40 GMT
470 // or
471 // Sat, 01-Jan-2000 08:00:00 GMT
472 // or
473 // Sat, 01 Jan 2000 08:00:00 GMT
474 // or
475 // 01 Jan 99 22:00 +0100 (exceptions in rfc822/rfc2822)
476 // ### non RFC formats, added for Javascript:
477 // [Wednesday] January 09 1999 23:12:40 GMT
478 // [Wednesday] January 09 23:12:40 GMT 1999
479 //
480 // We ignore the weekday.
481
482 // Skip leading space
483 skipSpacesAndComments(dateString);
484
485 long month = -1;
486 const char* wordStart = dateString;
487 // Check contents of first words if not number
488 while (*dateString && !isASCIIDigit(*dateString)) {
489 if (isASCIISpace(*dateString) || *dateString == '(') {
490 if (dateString - wordStart >= 3)
491 month = findMonth(wordStart);
492 skipSpacesAndComments(dateString);
493 wordStart = dateString;
494 } else {
495 dateString++;
496 }
497 }
498
499 // Missing delimiter between month and day (like "January29")?
500 if (month == -1 && wordStart != dateString)
501 month = findMonth(wordStart);
502
503 skipSpacesAndComments(dateString);
504
505 if (!*dateString)
506 return std::numeric_limits<double>::quiet_NaN();
507
508 // ' 09-Nov-99 23:12:40 GMT'
509 char* newPosStr;
510 long day;
511 if (!parseLong(dateString, &newPosStr, 10, &day))
512 return std::numeric_limits<double>::quiet_NaN();
513 dateString = newPosStr;
514
515 if (!*dateString)
516 return std::numeric_limits<double>::quiet_NaN();
517
518 if (day < 0)
519 return std::numeric_limits<double>::quiet_NaN();
520
521 int year = 0;
522 if (day > 31) {
523 // ### where is the boundary and what happens below?
524 if (*dateString != '/')
525 return std::numeric_limits<double>::quiet_NaN();
526 // looks like a YYYY/MM/DD date
527 if (!*++dateString)
528 return std::numeric_limits<double>::quiet_NaN();
529 if (day <= std::numeric_limits<int>::min() || day >= std::numeric_limits<int >::max())
530 return std::numeric_limits<double>::quiet_NaN();
531 year = static_cast<int>(day);
532 if (!parseLong(dateString, &newPosStr, 10, &month))
533 return std::numeric_limits<double>::quiet_NaN();
534 month -= 1;
535 dateString = newPosStr;
536 if (*dateString++ != '/' || !*dateString)
537 return std::numeric_limits<double>::quiet_NaN();
538 if (!parseLong(dateString, &newPosStr, 10, &day))
539 return std::numeric_limits<double>::quiet_NaN();
540 dateString = newPosStr;
541 } else if (*dateString == '/' && month == -1) {
542 dateString++;
543 // This looks like a MM/DD/YYYY date, not an RFC date.
544 month = day - 1; // 0-based
545 if (!parseLong(dateString, &newPosStr, 10, &day))
546 return std::numeric_limits<double>::quiet_NaN();
547 if (day < 1 || day > 31)
548 return std::numeric_limits<double>::quiet_NaN();
549 dateString = newPosStr;
550 if (*dateString == '/')
551 dateString++;
552 if (!*dateString)
553 return std::numeric_limits<double>::quiet_NaN();
554 } else {
555 if (*dateString == '-')
556 dateString++;
557
558 skipSpacesAndComments(dateString);
559
560 if (*dateString == ',')
561 dateString++;
562
563 if (month == -1) { // not found yet
564 month = findMonth(dateString);
565 if (month == -1)
566 return std::numeric_limits<double>::quiet_NaN();
567
568 while (*dateString && *dateString != '-' && *dateString != ',' && !isASCII Space(*dateString))
569 dateString++;
570
571 if (!*dateString)
572 return std::numeric_limits<double>::quiet_NaN();
573
574 // '-99 23:12:40 GMT'
575 if (*dateString != '-' && *dateString != '/' && *dateString != ',' && !isA SCIISpace(*dateString))
576 return std::numeric_limits<double>::quiet_NaN();
577 dateString++;
578 }
579 }
580
581 if (month < 0 || month > 11)
582 return std::numeric_limits<double>::quiet_NaN();
583
584 // '99 23:12:40 GMT'
585 if (year <= 0 && *dateString) {
586 if (!parseInt(dateString, &newPosStr, 10, &year))
587 return std::numeric_limits<double>::quiet_NaN();
588 }
589
590 // Don't fail if the time is missing.
591 long hour = 0;
592 long minute = 0;
593 long second = 0;
594 if (!*newPosStr) {
595 dateString = newPosStr;
596 } else {
597 // ' 23:12:40 GMT'
598 if (!(isASCIISpace(*newPosStr) || *newPosStr == ',')) {
599 if (*newPosStr != ':')
600 return std::numeric_limits<double>::quiet_NaN();
601 // There was no year; the number was the hour.
602 year = -1;
603 } else {
604 // in the normal case (we parsed the year), advance to the next number
605 dateString = ++newPosStr;
606 skipSpacesAndComments(dateString);
607 }
608
609 parseLong(dateString, &newPosStr, 10, &hour);
610 // Do not check for errno here since we want to continue
611 // even if errno was set becasue we are still looking
612 // for the timezone!
613
614 // Read a number? If not, this might be a timezone name.
615 if (newPosStr != dateString) {
616 dateString = newPosStr;
617
618 if (hour < 0 || hour > 23)
619 return std::numeric_limits<double>::quiet_NaN();
620
621 if (!*dateString)
622 return std::numeric_limits<double>::quiet_NaN();
623
624 // ':12:40 GMT'
625 if (*dateString++ != ':')
626 return std::numeric_limits<double>::quiet_NaN();
627
628 if (!parseLong(dateString, &newPosStr, 10, &minute))
629 return std::numeric_limits<double>::quiet_NaN();
630 dateString = newPosStr;
631
632 if (minute < 0 || minute > 59)
633 return std::numeric_limits<double>::quiet_NaN();
634
635 // ':40 GMT'
636 if (*dateString && *dateString != ':' && !isASCIISpace(*dateString))
637 return std::numeric_limits<double>::quiet_NaN();
638
639 // seconds are optional in rfc822 + rfc2822
640 if (*dateString == ':') {
641 dateString++;
642
643 if (!parseLong(dateString, &newPosStr, 10, &second))
644 return std::numeric_limits<double>::quiet_NaN();
645 dateString = newPosStr;
646
647 if (second < 0 || second > 59)
648 return std::numeric_limits<double>::quiet_NaN();
649 }
650
651 skipSpacesAndComments(dateString);
652
653 if (strncasecmp(dateString, "AM", 2) == 0) {
654 if (hour > 12)
655 return std::numeric_limits<double>::quiet_NaN();
656 if (hour == 12)
657 hour = 0;
658 dateString += 2;
659 skipSpacesAndComments(dateString);
660 } else if (strncasecmp(dateString, "PM", 2) == 0) {
661 if (hour > 12)
662 return std::numeric_limits<double>::quiet_NaN();
663 if (hour != 12)
664 hour += 12;
665 dateString += 2;
666 skipSpacesAndComments(dateString);
667 }
668 }
669 }
670
671 // The year may be after the time but before the time zone.
672 if (isASCIIDigit(*dateString) && year == -1) {
673 if (!parseInt(dateString, &newPosStr, 10, &year))
674 return std::numeric_limits<double>::quiet_NaN();
675 dateString = newPosStr;
676 skipSpacesAndComments(dateString);
677 }
678
679 // Don't fail if the time zone is missing.
680 // Some websites omit the time zone (4275206).
681 if (*dateString) {
682 if (strncasecmp(dateString, "GMT", 3) == 0 || strncasecmp(dateString, "UTC", 3) == 0) {
683 dateString += 3;
684 haveTZ = true;
685 }
686
687 if (*dateString == '+' || *dateString == '-') {
688 int o;
689 if (!parseInt(dateString, &newPosStr, 10, &o))
690 return std::numeric_limits<double>::quiet_NaN();
691 dateString = newPosStr;
692
693 if (o < -9959 || o > 9959)
694 return std::numeric_limits<double>::quiet_NaN();
695
696 int sgn = (o < 0) ? -1 : 1;
697 o = abs(o);
698 if (*dateString != ':') {
699 if (o >= 24)
700 offset = ((o / 100) * 60 + (o % 100)) * sgn;
701 else
702 offset = o * 60 * sgn;
703 } else { // GMT+05:00
704 ++dateString; // skip the ':'
705 int o2;
706 if (!parseInt(dateString, &newPosStr, 10, &o2))
707 return std::numeric_limits<double>::quiet_NaN();
708 dateString = newPosStr;
709 offset = (o * 60 + o2) * sgn;
710 }
711 haveTZ = true;
712 } else {
713 for (size_t i = 0; i < WTF_ARRAY_LENGTH(known_zones); ++i) {
714 if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zon es[i].tzName))) {
715 offset = known_zones[i].tzOffset;
716 dateString += strlen(known_zones[i].tzName);
717 haveTZ = true;
718 break;
451 } 719 }
452 s++; 720 }
453 } 721 }
454 } 722 }
455 723
456 // returns 0-11 (Jan-Dec); -1 on failure 724 skipSpacesAndComments(dateString);
457 static int findMonth(const char* monthStr) 725
458 { 726 if (*dateString && year == -1) {
459 ASSERT(monthStr); 727 if (!parseInt(dateString, &newPosStr, 10, &year))
460 char needle[4]; 728 return std::numeric_limits<double>::quiet_NaN();
461 for (int i = 0; i < 3; ++i) { 729 dateString = newPosStr;
462 if (!*monthStr)
463 return -1;
464 needle[i] = static_cast<char>(toASCIILower(*monthStr++));
465 }
466 needle[3] = '\0';
467 const char *haystack = "janfebmaraprmayjunjulaugsepoctnovdec";
468 const char *str = strstr(haystack, needle);
469 if (str) {
470 int position = static_cast<int>(str - haystack);
471 if (position % 3 == 0)
472 return position / 3;
473 }
474 return -1;
475 }
476
477 static bool parseInt(const char* string, char** stopPosition, int base, int* res ult)
478 {
479 long longResult = strtol(string, stopPosition, base);
480 // Avoid the use of errno as it is not available on Windows CE
481 if (string == *stopPosition || longResult <= std::numeric_limits<int>::min() || longResult >= std::numeric_limits<int>::max())
482 return false;
483 *result = static_cast<int>(longResult);
484 return true;
485 }
486
487 static bool parseLong(const char* string, char** stopPosition, int base, long* r esult)
488 {
489 *result = strtol(string, stopPosition, base);
490 // Avoid the use of errno as it is not available on Windows CE
491 if (string == *stopPosition || *result == std::numeric_limits<long>::min() | | *result == std::numeric_limits<long>::max())
492 return false;
493 return true;
494 }
495
496 // Odd case where 'exec' is allowed to be 0, to accomodate a caller in WebCore.
497 static double parseDateFromNullTerminatedCharacters(const char* dateString, bool & haveTZ, int& offset)
498 {
499 haveTZ = false;
500 offset = 0;
501
502 // This parses a date in the form:
503 // Tuesday, 09-Nov-99 23:12:40 GMT
504 // or
505 // Sat, 01-Jan-2000 08:00:00 GMT
506 // or
507 // Sat, 01 Jan 2000 08:00:00 GMT
508 // or
509 // 01 Jan 99 22:00 +0100 (exceptions in rfc822/rfc2822)
510 // ### non RFC formats, added for Javascript:
511 // [Wednesday] January 09 1999 23:12:40 GMT
512 // [Wednesday] January 09 23:12:40 GMT 1999
513 //
514 // We ignore the weekday.
515
516 // Skip leading space
517 skipSpacesAndComments(dateString); 730 skipSpacesAndComments(dateString);
518 731 }
519 long month = -1; 732
520 const char *wordStart = dateString; 733 // Trailing garbage
521 // Check contents of first words if not number 734 if (*dateString)
522 while (*dateString && !isASCIIDigit(*dateString)) { 735 return std::numeric_limits<double>::quiet_NaN();
523 if (isASCIISpace(*dateString) || *dateString == '(') { 736
524 if (dateString - wordStart >= 3) 737 // Y2K: Handle 2 digit years.
525 month = findMonth(wordStart); 738 if (year >= 0 && year < 100) {
526 skipSpacesAndComments(dateString); 739 if (year < 50)
527 wordStart = dateString; 740 year += 2000;
528 } else { 741 else
529 dateString++; 742 year += 1900;
530 } 743 }
531 } 744
532 745 return ymdhmsToSeconds(year, month + 1, day, hour, minute, second) * msPerSeco nd;
533 // Missing delimiter between month and day (like "January29")? 746 }
534 if (month == -1 && wordStart != dateString) 747
535 month = findMonth(wordStart); 748 double parseDateFromNullTerminatedCharacters(const char* dateString) {
536 749 bool haveTZ;
537 skipSpacesAndComments(dateString); 750 int offset;
538 751 double ms = parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
539 if (!*dateString) 752 if (std::isnan(ms))
540 return std::numeric_limits<double>::quiet_NaN(); 753 return std::numeric_limits<double>::quiet_NaN();
541 754
542 // ' 09-Nov-99 23:12:40 GMT' 755 // fall back to local timezone
543 char* newPosStr; 756 if (!haveTZ) {
544 long day;
545 if (!parseLong(dateString, &newPosStr, 10, &day))
546 return std::numeric_limits<double>::quiet_NaN();
547 dateString = newPosStr;
548
549 if (!*dateString)
550 return std::numeric_limits<double>::quiet_NaN();
551
552 if (day < 0)
553 return std::numeric_limits<double>::quiet_NaN();
554
555 int year = 0;
556 if (day > 31) {
557 // ### where is the boundary and what happens below?
558 if (*dateString != '/')
559 return std::numeric_limits<double>::quiet_NaN();
560 // looks like a YYYY/MM/DD date
561 if (!*++dateString)
562 return std::numeric_limits<double>::quiet_NaN();
563 if (day <= std::numeric_limits<int>::min() || day >= std::numeric_limits <int>::max())
564 return std::numeric_limits<double>::quiet_NaN();
565 year = static_cast<int>(day);
566 if (!parseLong(dateString, &newPosStr, 10, &month))
567 return std::numeric_limits<double>::quiet_NaN();
568 month -= 1;
569 dateString = newPosStr;
570 if (*dateString++ != '/' || !*dateString)
571 return std::numeric_limits<double>::quiet_NaN();
572 if (!parseLong(dateString, &newPosStr, 10, &day))
573 return std::numeric_limits<double>::quiet_NaN();
574 dateString = newPosStr;
575 } else if (*dateString == '/' && month == -1) {
576 dateString++;
577 // This looks like a MM/DD/YYYY date, not an RFC date.
578 month = day - 1; // 0-based
579 if (!parseLong(dateString, &newPosStr, 10, &day))
580 return std::numeric_limits<double>::quiet_NaN();
581 if (day < 1 || day > 31)
582 return std::numeric_limits<double>::quiet_NaN();
583 dateString = newPosStr;
584 if (*dateString == '/')
585 dateString++;
586 if (!*dateString)
587 return std::numeric_limits<double>::quiet_NaN();
588 } else {
589 if (*dateString == '-')
590 dateString++;
591
592 skipSpacesAndComments(dateString);
593
594 if (*dateString == ',')
595 dateString++;
596
597 if (month == -1) { // not found yet
598 month = findMonth(dateString);
599 if (month == -1)
600 return std::numeric_limits<double>::quiet_NaN();
601
602 while (*dateString && *dateString != '-' && *dateString != ',' && !i sASCIISpace(*dateString))
603 dateString++;
604
605 if (!*dateString)
606 return std::numeric_limits<double>::quiet_NaN();
607
608 // '-99 23:12:40 GMT'
609 if (*dateString != '-' && *dateString != '/' && *dateString != ',' & & !isASCIISpace(*dateString))
610 return std::numeric_limits<double>::quiet_NaN();
611 dateString++;
612 }
613 }
614
615 if (month < 0 || month > 11)
616 return std::numeric_limits<double>::quiet_NaN();
617
618 // '99 23:12:40 GMT'
619 if (year <= 0 && *dateString) {
620 if (!parseInt(dateString, &newPosStr, 10, &year))
621 return std::numeric_limits<double>::quiet_NaN();
622 }
623
624 // Don't fail if the time is missing.
625 long hour = 0;
626 long minute = 0;
627 long second = 0;
628 if (!*newPosStr) {
629 dateString = newPosStr;
630 } else {
631 // ' 23:12:40 GMT'
632 if (!(isASCIISpace(*newPosStr) || *newPosStr == ',')) {
633 if (*newPosStr != ':')
634 return std::numeric_limits<double>::quiet_NaN();
635 // There was no year; the number was the hour.
636 year = -1;
637 } else {
638 // in the normal case (we parsed the year), advance to the next numb er
639 dateString = ++newPosStr;
640 skipSpacesAndComments(dateString);
641 }
642
643 parseLong(dateString, &newPosStr, 10, &hour);
644 // Do not check for errno here since we want to continue
645 // even if errno was set becasue we are still looking
646 // for the timezone!
647
648 // Read a number? If not, this might be a timezone name.
649 if (newPosStr != dateString) {
650 dateString = newPosStr;
651
652 if (hour < 0 || hour > 23)
653 return std::numeric_limits<double>::quiet_NaN();
654
655 if (!*dateString)
656 return std::numeric_limits<double>::quiet_NaN();
657
658 // ':12:40 GMT'
659 if (*dateString++ != ':')
660 return std::numeric_limits<double>::quiet_NaN();
661
662 if (!parseLong(dateString, &newPosStr, 10, &minute))
663 return std::numeric_limits<double>::quiet_NaN();
664 dateString = newPosStr;
665
666 if (minute < 0 || minute > 59)
667 return std::numeric_limits<double>::quiet_NaN();
668
669 // ':40 GMT'
670 if (*dateString && *dateString != ':' && !isASCIISpace(*dateString))
671 return std::numeric_limits<double>::quiet_NaN();
672
673 // seconds are optional in rfc822 + rfc2822
674 if (*dateString ==':') {
675 dateString++;
676
677 if (!parseLong(dateString, &newPosStr, 10, &second))
678 return std::numeric_limits<double>::quiet_NaN();
679 dateString = newPosStr;
680
681 if (second < 0 || second > 59)
682 return std::numeric_limits<double>::quiet_NaN();
683 }
684
685 skipSpacesAndComments(dateString);
686
687 if (strncasecmp(dateString, "AM", 2) == 0) {
688 if (hour > 12)
689 return std::numeric_limits<double>::quiet_NaN();
690 if (hour == 12)
691 hour = 0;
692 dateString += 2;
693 skipSpacesAndComments(dateString);
694 } else if (strncasecmp(dateString, "PM", 2) == 0) {
695 if (hour > 12)
696 return std::numeric_limits<double>::quiet_NaN();
697 if (hour != 12)
698 hour += 12;
699 dateString += 2;
700 skipSpacesAndComments(dateString);
701 }
702 }
703 }
704
705 // The year may be after the time but before the time zone.
706 if (isASCIIDigit(*dateString) && year == -1) {
707 if (!parseInt(dateString, &newPosStr, 10, &year))
708 return std::numeric_limits<double>::quiet_NaN();
709 dateString = newPosStr;
710 skipSpacesAndComments(dateString);
711 }
712
713 // Don't fail if the time zone is missing.
714 // Some websites omit the time zone (4275206).
715 if (*dateString) {
716 if (strncasecmp(dateString, "GMT", 3) == 0 || strncasecmp(dateString, "U TC", 3) == 0) {
717 dateString += 3;
718 haveTZ = true;
719 }
720
721 if (*dateString == '+' || *dateString == '-') {
722 int o;
723 if (!parseInt(dateString, &newPosStr, 10, &o))
724 return std::numeric_limits<double>::quiet_NaN();
725 dateString = newPosStr;
726
727 if (o < -9959 || o > 9959)
728 return std::numeric_limits<double>::quiet_NaN();
729
730 int sgn = (o < 0) ? -1 : 1;
731 o = abs(o);
732 if (*dateString != ':') {
733 if (o >= 24)
734 offset = ((o / 100) * 60 + (o % 100)) * sgn;
735 else
736 offset = o * 60 * sgn;
737 } else { // GMT+05:00
738 ++dateString; // skip the ':'
739 int o2;
740 if (!parseInt(dateString, &newPosStr, 10, &o2))
741 return std::numeric_limits<double>::quiet_NaN();
742 dateString = newPosStr;
743 offset = (o * 60 + o2) * sgn;
744 }
745 haveTZ = true;
746 } else {
747 for (size_t i = 0; i < WTF_ARRAY_LENGTH(known_zones); ++i) {
748 if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(k nown_zones[i].tzName))) {
749 offset = known_zones[i].tzOffset;
750 dateString += strlen(known_zones[i].tzName);
751 haveTZ = true;
752 break;
753 }
754 }
755 }
756 }
757
758 skipSpacesAndComments(dateString);
759
760 if (*dateString && year == -1) {
761 if (!parseInt(dateString, &newPosStr, 10, &year))
762 return std::numeric_limits<double>::quiet_NaN();
763 dateString = newPosStr;
764 skipSpacesAndComments(dateString);
765 }
766
767 // Trailing garbage
768 if (*dateString)
769 return std::numeric_limits<double>::quiet_NaN();
770
771 // Y2K: Handle 2 digit years.
772 if (year >= 0 && year < 100) {
773 if (year < 50)
774 year += 2000;
775 else
776 year += 1900;
777 }
778
779 return ymdhmsToSeconds(year, month + 1, day, hour, minute, second) * msPerSe cond;
780 }
781
782 double parseDateFromNullTerminatedCharacters(const char* dateString)
783 {
784 bool haveTZ;
785 int offset;
786 double ms = parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset );
787 if (std::isnan(ms))
788 return std::numeric_limits<double>::quiet_NaN();
789
790 // fall back to local timezone
791 if (!haveTZ) {
792 double utcOffset = calculateUTCOffset();
793 double dstOffset = calculateDSTOffset(ms, utcOffset);
794 offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
795 }
796 return ms - (offset * msPerMinute);
797 }
798
799 // See http://tools.ietf.org/html/rfc2822#section-3.3 for more information.
800 String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, u nsigned year, unsigned hours, unsigned minutes, unsigned seconds, int utcOffset)
801 {
802 StringBuilder stringBuilder;
803 stringBuilder.append(weekdayName[dayOfWeek]);
804 stringBuilder.appendLiteral(", ");
805 stringBuilder.appendNumber(day);
806 stringBuilder.append(' ');
807 stringBuilder.append(monthName[month]);
808 stringBuilder.append(' ');
809 stringBuilder.appendNumber(year);
810 stringBuilder.append(' ');
811
812 appendTwoDigitNumber(stringBuilder, hours);
813 stringBuilder.append(':');
814 appendTwoDigitNumber(stringBuilder, minutes);
815 stringBuilder.append(':');
816 appendTwoDigitNumber(stringBuilder, seconds);
817 stringBuilder.append(' ');
818
819 stringBuilder.append(utcOffset > 0 ? '+' : '-');
820 int absoluteUTCOffset = abs(utcOffset);
821 appendTwoDigitNumber(stringBuilder, absoluteUTCOffset / 60);
822 appendTwoDigitNumber(stringBuilder, absoluteUTCOffset % 60);
823
824 return stringBuilder.toString();
825 }
826
827 double convertToLocalTime(double ms)
828 {
829 double utcOffset = calculateUTCOffset(); 757 double utcOffset = calculateUTCOffset();
830 double dstOffset = calculateDSTOffset(ms, utcOffset); 758 double dstOffset = calculateDSTOffset(ms, utcOffset);
831 return (ms + utcOffset + dstOffset); 759 offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
832 } 760 }
833 761 return ms - (offset * msPerMinute);
834 } // namespace WTF 762 }
763
764 // See http://tools.ietf.org/html/rfc2822#section-3.3 for more information.
765 String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, u nsigned year, unsigned hours, unsigned minutes, unsigned seconds, int utcOffset) {
766 StringBuilder stringBuilder;
767 stringBuilder.append(weekdayName[dayOfWeek]);
768 stringBuilder.appendLiteral(", ");
769 stringBuilder.appendNumber(day);
770 stringBuilder.append(' ');
771 stringBuilder.append(monthName[month]);
772 stringBuilder.append(' ');
773 stringBuilder.appendNumber(year);
774 stringBuilder.append(' ');
775
776 appendTwoDigitNumber(stringBuilder, hours);
777 stringBuilder.append(':');
778 appendTwoDigitNumber(stringBuilder, minutes);
779 stringBuilder.append(':');
780 appendTwoDigitNumber(stringBuilder, seconds);
781 stringBuilder.append(' ');
782
783 stringBuilder.append(utcOffset > 0 ? '+' : '-');
784 int absoluteUTCOffset = abs(utcOffset);
785 appendTwoDigitNumber(stringBuilder, absoluteUTCOffset / 60);
786 appendTwoDigitNumber(stringBuilder, absoluteUTCOffset % 60);
787
788 return stringBuilder.toString();
789 }
790
791 double convertToLocalTime(double ms) {
792 double utcOffset = calculateUTCOffset();
793 double dstOffset = calculateDSTOffset(ms, utcOffset);
794 return (ms + utcOffset + dstOffset);
795 }
796
797 } // namespace WTF
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/DateMath.h ('k') | third_party/WebKit/Source/wtf/Deque.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698