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

Side by Side Diff: runtime/lib/date_patch.dart

Issue 1845483002: Fix core lib DateTime in the VM. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months 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
« runtime/lib/date.cc ('K') | « runtime/lib/date.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 // Dart core library. 4 // Dart core library.
5 5
6 // VM implementation of DateTime. 6 // VM implementation of DateTime.
7 patch class DateTime { 7 patch class DateTime {
8 // Natives. 8 // Natives.
9 // The natives have been moved up here to work around Issue 10401. 9 // The natives have been moved up here to work around Issue 10401.
10 static int _getCurrentMicros() native "DateTime_currentTimeMicros"; 10 static int _getCurrentMicros() native "DateTime_currentTimeMicros";
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 // the valid range we do a preliminary test that weeds out values that can 277 // the valid range we do a preliminary test that weeds out values that can
278 // not become valid even with timezone adjustments. 278 // not become valid even with timezone adjustments.
279 // The timezone adjustment is always less than a day, so adding a security 279 // The timezone adjustment is always less than a day, so adding a security
280 // margin of one day should be enough. 280 // margin of one day should be enough.
281 if (microsecondsSinceEpoch.abs() > 281 if (microsecondsSinceEpoch.abs() >
282 _MAX_MILLISECONDS_SINCE_EPOCH * 1000 + Duration.MICROSECONDS_PER_DAY) { 282 _MAX_MILLISECONDS_SINCE_EPOCH * 1000 + Duration.MICROSECONDS_PER_DAY) {
283 return null; 283 return null;
284 } 284 }
285 285
286 if (!isUtc) { 286 if (!isUtc) {
287 // Note that we need to remove the local timezone adjustement before 287 // Note that we need to remove the local timezone adjustment before
288 // asking for the correct zone offset. 288 // asking for the correct zone offset.
289 int adjustment = _localTimeZoneAdjustmentInSeconds() * 289 int adjustment = _localTimeZoneAdjustmentInSeconds() *
290 Duration.MICROSECONDS_PER_SECOND; 290 Duration.MICROSECONDS_PER_SECOND;
291 // The adjustment is independent of the actual date and of the daylight
292 // saving time. It is positive east of the Prime Meridian and negative
293 // west of it, e.g. -28800000 for America/Los_Angeles timezone.
291 294
292 int zoneOffset = 295 int zoneOffset =
293 _timeZoneOffsetInSeconds(microsecondsSinceEpoch - adjustment); 296 _timeZoneOffsetInSeconds(microsecondsSinceEpoch - adjustment);
297 // The zoneOffset depends on the actual date and reflects any daylight
298 // saving time and/or historical deviation relative to UTC time.
299 // It is positive east of the Prime Meridian and negative
300 // west of it, e.g. -25200000 for America/Los_Angeles timezone during DST.
294 microsecondsSinceEpoch -= zoneOffset * Duration.MICROSECONDS_PER_SECOND; 301 microsecondsSinceEpoch -= zoneOffset * Duration.MICROSECONDS_PER_SECOND;
295 } 302 }
296 if (microsecondsSinceEpoch.abs() > 303 if (microsecondsSinceEpoch.abs() >
297 _MAX_MILLISECONDS_SINCE_EPOCH * Duration.MICROSECONDS_PER_MILLISECOND) { 304 _MAX_MILLISECONDS_SINCE_EPOCH * Duration.MICROSECONDS_PER_MILLISECOND) {
298 return null; 305 return null;
299 } 306 }
300 return microsecondsSinceEpoch; 307 return microsecondsSinceEpoch;
301 } 308 }
302 309
303 static int _weekDay(y) { 310 static int _weekDay(y) {
304 // 1/1/1970 was a Thursday. 311 // 1/1/1970 was a Thursday.
305 return (_dayFromYear(y) + 4) % 7; 312 return (_dayFromYear(y) + 4) % 7;
306 } 313 }
307 314
308 /** 315 /**
309 * Returns a year in the range 2008-2035 matching 316 * Returns a year in the range 2008-2035 matching
310 * * leap year, and 317 * * leap year, and
311 * * week day of first day. 318 * * week day of first day.
312 * 319 *
313 * Leap seconds are ignored. 320 * Leap seconds are ignored.
314 * Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9. 321 * Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9.
315 */ 322 */
316 static int _equivalentYear(int year) { 323 static int _equivalentYear(int year) {
317 // Returns the week day (in range 0 - 6). 324 // Returns year y so that _weekDay(y) == _weekDay(year).
325 // _weekDay returns the week day (in range 0 - 6).
318 // 1/1/1956 was a Sunday (i.e. weekday 0). 1956 was a leap-year. 326 // 1/1/1956 was a Sunday (i.e. weekday 0). 1956 was a leap-year.
319 // 1/1/1967 was a Sunday (i.e. weekday 0). 327 // 1/1/1967 was a Sunday (i.e. weekday 0).
320 // Without leap years a subsequent year has a week day + 1 (for example 328 // Without leap years a subsequent year has a week day + 1 (for example
321 // 1/1/1968 was a Monday). With leap-years it jumps over one week day 329 // 1/1/1968 was a Monday). With leap-years it jumps over one week day
322 // (e.g. 1/1/1957 was a Tuesday). 330 // (e.g. 1/1/1957 was a Tuesday).
323 // After 12 years the weekdays have advanced by 12 days + 3 leap days = 331 // After 12 years the weekdays have advanced by 12 days + 3 leap days =
324 // 15 days. 15 % 7 = 1. So after 12 years the week day has always 332 // 15 days. 15 % 7 = 1. So after 12 years the week day has always
325 // (now independently of leap-years) advanced by one. 333 // (now independently of leap-years) advanced by one.
326 // weekDay * 12 gives thus a year starting with the wanted weekDay. 334 // weekDay * 12 gives thus a year starting with the wanted weekDay.
327 int recentYear = (_isLeapYear(year) ? 1956 : 1967) + (_weekDay(year) * 12); 335 int recentYear = (_isLeapYear(year) ? 1956 : 1967) + (_weekDay(year) * 12);
(...skipping 17 matching lines...) Expand all
345 int days = secondsSinceEpoch ~/ Duration.SECONDS_PER_DAY; 353 int days = secondsSinceEpoch ~/ Duration.SECONDS_PER_DAY;
346 if (days > 0 && days < DAYS_YEAR_2098) { 354 if (days > 0 && days < DAYS_YEAR_2098) {
347 // According to V8 this fast case works for dates from 1970 to 2099. 355 // According to V8 this fast case works for dates from 1970 to 2099.
348 return 1970 + (4 * days + 2) ~/ DAYS_IN_4_YEARS; 356 return 1970 + (4 * days + 2) ~/ DAYS_IN_4_YEARS;
349 } 357 }
350 int micros = secondsSinceEpoch * Duration.MICROSECONDS_PER_SECOND; 358 int micros = secondsSinceEpoch * Duration.MICROSECONDS_PER_SECOND;
351 return _computeUpperPart(micros)[_YEAR_INDEX]; 359 return _computeUpperPart(micros)[_YEAR_INDEX];
352 } 360 }
353 361
354 /** 362 /**
355 * Returns a date in seconds that is equivalent to the current date. An 363 * Returns a date in seconds that is equivalent to the given
356 * equivalent date has the same fields (`month`, `day`, etc.) as the 364 * date in microseconds [microsecondsSinceEpoch]. An equivalent
357 * [this], but the `year` is in the range [1970..2037]. 365 * date has the same fields (`month`, `day`, etc.) as the given
366 * date, but the `year` is in the range [1901..2038].
358 * 367 *
359 * * The time since the beginning of the year is the same. 368 * * The time since the beginning of the year is the same.
360 * * If [this] is in a leap year then the returned seconds are in a leap 369 * * If the given date is in a leap year then the returned
361 * year, too. 370 * seconds are in a leap year, too.
362 * * The week day of [this] is the same as the one for the returned date. 371 * * The week day of given date is the same as the one for the
372 * returned date.
363 */ 373 */
364 static int _equivalentSeconds(int microsecondsSinceEpoch) { 374 static int _equivalentSeconds(int microsecondsSinceEpoch) {
365 const int CUT_OFF_SECONDS = 2100000000; 375 const int CUT_OFF_SECONDS = 0x7FFFFFFF;
366 376
367 int secondsSinceEpoch = _flooredDivision(microsecondsSinceEpoch, 377 int secondsSinceEpoch = _flooredDivision(microsecondsSinceEpoch,
368 Duration.MICROSECONDS_PER_SECOND); 378 Duration.MICROSECONDS_PER_SECOND);
369 379
370 if (secondsSinceEpoch < 0 || secondsSinceEpoch >= CUT_OFF_SECONDS) { 380 if (secondsSinceEpoch.abs() > CUT_OFF_SECONDS) {
371 int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch); 381 int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch);
372 int days = _dayFromYear(year); 382 int days = _dayFromYear(year);
373 int equivalentYear = _equivalentYear(year); 383 int equivalentYear = _equivalentYear(year);
374 int equivalentDays = _dayFromYear(equivalentYear); 384 int equivalentDays = _dayFromYear(equivalentYear);
375 int diffDays = equivalentDays - days; 385 int diffDays = equivalentDays - days;
376 secondsSinceEpoch += diffDays * Duration.SECONDS_PER_DAY; 386 secondsSinceEpoch += diffDays * Duration.SECONDS_PER_DAY;
377 } 387 }
378 return secondsSinceEpoch; 388 return secondsSinceEpoch;
379 } 389 }
380 390
381 static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) { 391 static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) {
382 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch); 392 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
383 return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds); 393 return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds);
384 } 394 }
385 395
386 static String _timeZoneName(int microsecondsSinceEpoch) { 396 static String _timeZoneName(int microsecondsSinceEpoch) {
387 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch); 397 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
388 return _timeZoneNameForClampedSeconds(equivalentSeconds); 398 return _timeZoneNameForClampedSeconds(equivalentSeconds);
389 } 399 }
390 } 400 }
OLDNEW
« runtime/lib/date.cc ('K') | « runtime/lib/date.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698