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

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: adress comments 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
« no previous file with comments | « 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. -28800 sec 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 west of it,
300 // e.g. -25200 sec for America/Los_Angeles timezone during DST.
294 microsecondsSinceEpoch -= zoneOffset * Duration.MICROSECONDS_PER_SECOND; 301 microsecondsSinceEpoch -= zoneOffset * Duration.MICROSECONDS_PER_SECOND;
302 // The resulting microsecondsSinceEpoch value is therefore the calculated
303 // UTC value decreased by a (positive if east of GMT) timezone adjustment
304 // and decreased by typically one hour if DST is in effect.
295 } 305 }
296 if (microsecondsSinceEpoch.abs() > 306 if (microsecondsSinceEpoch.abs() >
297 _MAX_MILLISECONDS_SINCE_EPOCH * Duration.MICROSECONDS_PER_MILLISECOND) { 307 _MAX_MILLISECONDS_SINCE_EPOCH * Duration.MICROSECONDS_PER_MILLISECOND) {
298 return null; 308 return null;
299 } 309 }
300 return microsecondsSinceEpoch; 310 return microsecondsSinceEpoch;
301 } 311 }
302 312
303 static int _weekDay(y) { 313 static int _weekDay(y) {
304 // 1/1/1970 was a Thursday. 314 // 1/1/1970 was a Thursday.
305 return (_dayFromYear(y) + 4) % 7; 315 return (_dayFromYear(y) + 4) % 7;
306 } 316 }
307 317
308 /** 318 /**
309 * Returns a year in the range 2008-2035 matching 319 * Returns a year in the range 2008-2035 matching
310 * * leap year, and 320 * * leap year, and
311 * * week day of first day. 321 * * week day of first day.
312 * 322 *
313 * Leap seconds are ignored. 323 * Leap seconds are ignored.
314 * Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9. 324 * Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9.
315 */ 325 */
316 static int _equivalentYear(int year) { 326 static int _equivalentYear(int year) {
317 // Returns the week day (in range 0 - 6). 327 // Returns year y so that _weekDay(y) == _weekDay(year).
328 // _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. 329 // 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). 330 // 1/1/1967 was a Sunday (i.e. weekday 0).
320 // Without leap years a subsequent year has a week day + 1 (for example 331 // 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 332 // 1/1/1968 was a Monday). With leap-years it jumps over one week day
322 // (e.g. 1/1/1957 was a Tuesday). 333 // (e.g. 1/1/1957 was a Tuesday).
323 // After 12 years the weekdays have advanced by 12 days + 3 leap days = 334 // 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 335 // 15 days. 15 % 7 = 1. So after 12 years the week day has always
325 // (now independently of leap-years) advanced by one. 336 // (now independently of leap-years) advanced by one.
326 // weekDay * 12 gives thus a year starting with the wanted weekDay. 337 // weekDay * 12 gives thus a year starting with the wanted weekDay.
327 int recentYear = (_isLeapYear(year) ? 1956 : 1967) + (_weekDay(year) * 12); 338 int recentYear = (_isLeapYear(year) ? 1956 : 1967) + (_weekDay(year) * 12);
(...skipping 17 matching lines...) Expand all
345 int days = secondsSinceEpoch ~/ Duration.SECONDS_PER_DAY; 356 int days = secondsSinceEpoch ~/ Duration.SECONDS_PER_DAY;
346 if (days > 0 && days < DAYS_YEAR_2098) { 357 if (days > 0 && days < DAYS_YEAR_2098) {
347 // According to V8 this fast case works for dates from 1970 to 2099. 358 // According to V8 this fast case works for dates from 1970 to 2099.
348 return 1970 + (4 * days + 2) ~/ DAYS_IN_4_YEARS; 359 return 1970 + (4 * days + 2) ~/ DAYS_IN_4_YEARS;
349 } 360 }
350 int micros = secondsSinceEpoch * Duration.MICROSECONDS_PER_SECOND; 361 int micros = secondsSinceEpoch * Duration.MICROSECONDS_PER_SECOND;
351 return _computeUpperPart(micros)[_YEAR_INDEX]; 362 return _computeUpperPart(micros)[_YEAR_INDEX];
352 } 363 }
353 364
354 /** 365 /**
355 * Returns a date in seconds that is equivalent to the current date. An 366 * Returns a date in seconds that is equivalent to the given
356 * equivalent date has the same fields (`month`, `day`, etc.) as the 367 * date in microseconds [microsecondsSinceEpoch]. An equivalent
357 * [this], but the `year` is in the range [1970..2037]. 368 * date has the same fields (`month`, `day`, etc.) as the given
369 * date, but the `year` is in the range [1901..2038].
358 * 370 *
359 * * The time since the beginning of the year is the same. 371 * * 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 372 * * If the given date is in a leap year then the returned
361 * year, too. 373 * seconds are in a leap year, too.
362 * * The week day of [this] is the same as the one for the returned date. 374 * * The week day of given date is the same as the one for the
375 * returned date.
363 */ 376 */
364 static int _equivalentSeconds(int microsecondsSinceEpoch) { 377 static int _equivalentSeconds(int microsecondsSinceEpoch) {
365 const int CUT_OFF_SECONDS = 2100000000; 378 const int CUT_OFF_SECONDS = 0x7FFFFFFF;
366 379
367 int secondsSinceEpoch = _flooredDivision(microsecondsSinceEpoch, 380 int secondsSinceEpoch = _flooredDivision(microsecondsSinceEpoch,
368 Duration.MICROSECONDS_PER_SECOND); 381 Duration.MICROSECONDS_PER_SECOND);
369 382
370 if (secondsSinceEpoch < 0 || secondsSinceEpoch >= CUT_OFF_SECONDS) { 383 if (secondsSinceEpoch.abs() > CUT_OFF_SECONDS) {
371 int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch); 384 int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch);
372 int days = _dayFromYear(year); 385 int days = _dayFromYear(year);
373 int equivalentYear = _equivalentYear(year); 386 int equivalentYear = _equivalentYear(year);
374 int equivalentDays = _dayFromYear(equivalentYear); 387 int equivalentDays = _dayFromYear(equivalentYear);
375 int diffDays = equivalentDays - days; 388 int diffDays = equivalentDays - days;
376 secondsSinceEpoch += diffDays * Duration.SECONDS_PER_DAY; 389 secondsSinceEpoch += diffDays * Duration.SECONDS_PER_DAY;
377 } 390 }
378 return secondsSinceEpoch; 391 return secondsSinceEpoch;
379 } 392 }
380 393
381 static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) { 394 static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) {
382 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch); 395 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
383 return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds); 396 return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds);
384 } 397 }
385 398
386 static String _timeZoneName(int microsecondsSinceEpoch) { 399 static String _timeZoneName(int microsecondsSinceEpoch) {
387 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch); 400 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
388 return _timeZoneNameForClampedSeconds(equivalentSeconds); 401 return _timeZoneNameForClampedSeconds(equivalentSeconds);
389 } 402 }
390 } 403 }
OLDNEW
« no previous file with comments | « runtime/lib/date.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698