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

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

Issue 10832166: Updated VM and JS versions of Date to allow underflow and overflow. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: REmove extra days, add back throw expectation Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 DateImplementation. 6 // VM implementation of DateImplementation.
7 class DateImplementation implements Date { 7 class DateImplementation implements Date {
8 static final int _MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000; 8 static final int _MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
9 9
10 DateImplementation(int years, 10 DateImplementation(int year,
Lasse Reichstein Nielsen 2012/08/24 08:39:02 Please remove "Implementation". It's never a good
11 [int month = 1, 11 [int month = 1,
12 int day = 1, 12 int day = 1,
13 int hour = 0, 13 int hour = 0,
14 int minute = 0, 14 int minute = 0,
15 int second = 0, 15 int second = 0,
16 int millisecond = 0, 16 int millisecond = 0,
17 bool isUtc = false]) 17 bool isUtc = false])
18 : this.isUtc = isUtc, 18 : this.isUtc = isUtc,
19 this.millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch( 19 this.millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
20 years, month, day, hour, minute, second, millisecond, isUtc) { 20 year, month, day, hour, minute, second, millisecond, isUtc) {
21 if (millisecondsSinceEpoch === null) throw new IllegalArgumentException(); 21 if (millisecondsSinceEpoch === null) throw new IllegalArgumentException();
22 if (isUtc === null) throw new IllegalArgumentException(); 22 if (isUtc === null) throw new IllegalArgumentException();
23 } 23 }
24 24
25 DateImplementation.now() 25 DateImplementation.now()
26 : isUtc = false, 26 : isUtc = false,
27 millisecondsSinceEpoch = _getCurrentMs() { 27 millisecondsSinceEpoch = _getCurrentMs() {
28 } 28 }
29 29
30 factory DateImplementation.fromString(String formattedString) { 30 factory DateImplementation.fromString(String formattedString) {
(...skipping 16 matching lines...) Expand all
47 if (matched === null || matched == "") return 0; 47 if (matched === null || matched == "") return 0;
48 return Math.parseInt(matched); 48 return Math.parseInt(matched);
49 } 49 }
50 50
51 double parseDoubleOrZero(String matched) { 51 double parseDoubleOrZero(String matched) {
52 // TODO(floitsch): we should not need to test against the empty string. 52 // TODO(floitsch): we should not need to test against the empty string.
53 if (matched === null || matched == "") return 0.0; 53 if (matched === null || matched == "") return 0.0;
54 return Math.parseDouble(matched); 54 return Math.parseDouble(matched);
55 } 55 }
56 56
57 int years = Math.parseInt(match[1]); 57 int year = Math.parseInt(match[1]);
58 int month = Math.parseInt(match[2]); 58 int month = Math.parseInt(match[2]);
59 int day = Math.parseInt(match[3]); 59 int day = Math.parseInt(match[3]);
60 int hour = parseIntOrZero(match[4]); 60 int hour = parseIntOrZero(match[4]);
61 int minute = parseIntOrZero(match[5]); 61 int minute = parseIntOrZero(match[5]);
62 int second = parseIntOrZero(match[6]); 62 int second = parseIntOrZero(match[6]);
63 bool addOneMillisecond = false; 63 bool addOneMillisecond = false;
64 int millisecond = (parseDoubleOrZero(match[7]) * 1000).round().toInt(); 64 int millisecond = (parseDoubleOrZero(match[7]) * 1000).round().toInt();
65 if (millisecond == 1000) { 65 if (millisecond == 1000) {
66 addOneMillisecond = true; 66 addOneMillisecond = true;
67 millisecond = 999; 67 millisecond = 999;
68 } 68 }
69 // TODO(floitsch): we should not need to test against the empty string. 69 // TODO(floitsch): we should not need to test against the empty string.
70 bool isUtc = (match[8] !== null) && (match[8] != ""); 70 bool isUtc = (match[8] !== null) && (match[8] != "");
71 int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch( 71 int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
72 years, month, day, hour, minute, second, millisecond, isUtc); 72 year, month, day, hour, minute, second, millisecond, isUtc);
73 if (millisecondsSinceEpoch === null) { 73 if (millisecondsSinceEpoch === null) {
74 throw new IllegalArgumentException(formattedString); 74 throw new IllegalArgumentException(formattedString);
75 } 75 }
76 if (addOneMillisecond) millisecondsSinceEpoch++; 76 if (addOneMillisecond) millisecondsSinceEpoch++;
77 return new DateImplementation.fromMillisecondsSinceEpoch( 77 return new DateImplementation.fromMillisecondsSinceEpoch(
78 millisecondsSinceEpoch, isUtc); 78 millisecondsSinceEpoch, isUtc);
79 } else { 79 } else {
80 throw new IllegalArgumentException(formattedString); 80 throw new IllegalArgumentException(formattedString);
81 } 81 }
82 } 82 }
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 327
328 // Returns the days since 1970 for the start of the given [year]. 328 // Returns the days since 1970 for the start of the given [year].
329 // [year] may be before epoch. 329 // [year] may be before epoch.
330 static int _dayFromYear(int year) { 330 static int _dayFromYear(int year) {
331 return 365 * (year - 1970) 331 return 365 * (year - 1970)
332 + _flooredDivision(year - 1969, 4) 332 + _flooredDivision(year - 1969, 4)
333 - _flooredDivision(year - 1901, 100) 333 - _flooredDivision(year - 1901, 100)
334 + _flooredDivision(year - 1601, 400); 334 + _flooredDivision(year - 1601, 400);
335 } 335 }
336 336
337 static bool _isLeapYear(y) { 337 static bool _isLeapYear(y) {
Lasse Reichstein Nielsen 2012/08/24 08:39:02 Add type for "y". I think it's always int.
338 return (y.remainder(4) == 0) && 338 return (y.remainder(4) == 0) &&
339 ((y.remainder(100) != 0) || (y.remainder(400) == 0)); 339 ((y.remainder(100) != 0) || (y.remainder(400) == 0));
340 } 340 }
341 341
342 static _brokenDownDateToMillisecondsSinceEpoch( 342 static _brokenDownDateToMillisecondsSinceEpoch(
343 int years, int month, int day, 343 int year, int month, int day,
344 int hour, int minute, int second, int millisecond, 344 int hour, int minute, int second, int millisecond,
345 bool isUtc) { 345 bool isUtc) {
346 if ((month < 1) || (month > 12)) return null; 346 // JavaScript month is zero-based while Dart is one-based. This should
347 if ((day < 1) || (day > 31)) return null; 347 // simplify some calculations.
Lasse Reichstein Nielsen 2012/08/24 08:39:02 Why reference JavaScript here? This is VM code, ri
floitsch 2012/08/24 22:32:49 My fault.
348 // Leap seconds can lead to hour == 24. 348 --month;
349 if ((hour < 0) || (hour > 24)) return null; 349 // Deal with under and overflow.
350 if ((hour == 24) && ((minute != 0) || (second != 0))) return null; 350 year += (month / 12).floor().toInt();
351 if ((minute < 0) || (minute > 59)) return null; 351 month = month % 12;
352 if ((second < 0) || (second > 59)) return null; 352 int clampedMonth = month.remainder(12);
Lasse Reichstein Nielsen 2012/08/24 08:39:02 How can this be necessary when %12 above gives a v
floitsch 2012/08/24 22:32:49 Agreed. Either use year += month ~/ 12; clampedMo
353 if ((millisecond < 0) || (millisecond > 999)) return null; 353 if (clampedMonth < 0) {
354 --year;
355 clampedMonth += 12;
356 }
354 357
355 // First compute the seconds in UTC, independent of the [isUtc] flag. If 358 // First compute the seconds in UTC, independent of the [isUtc] flag. If
356 // necessary we will add the time-zone offset later on. 359 // necessary we will add the time-zone offset later on.
357 int days = day - 1; 360 int days = day - 1;
358 days += _DAYS_UNTIL_MONTH[_isLeapYear(years) ? 1 : 0][month - 1]; 361 days += _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][clampedMonth];
359 days += _dayFromYear(years); 362 days += _dayFromYear(year);
360 int millisecondsSinceEpoch = days * Duration.MILLISECONDS_PER_DAY + 363 int millisecondsSinceEpoch = days * Duration.MILLISECONDS_PER_DAY +
361 hour * Duration.MILLISECONDS_PER_HOUR + 364 hour * Duration.MILLISECONDS_PER_HOUR +
362 minute * Duration.MILLISECONDS_PER_MINUTE+ 365 minute * Duration.MILLISECONDS_PER_MINUTE+
363 second * Duration.MILLISECONDS_PER_SECOND + 366 second * Duration.MILLISECONDS_PER_SECOND +
364 millisecond; 367 millisecond;
365 368
366 // Since [_timeZoneOffsetInSeconds] will crash if the input is far out of 369 // Since [_timeZoneOffsetInSeconds] will crash if the input is far out of
367 // the valid range we do a preliminary test that weeds out values that can 370 // the valid range we do a preliminary test that weeds out values that can
368 // not become valid even with timezone adjustments. 371 // not become valid even with timezone adjustments.
369 // The timezone adjustment is always less than a day, so adding a security 372 // The timezone adjustment is always less than a day, so adding a security
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 486
484 static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch) 487 static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch)
485 native "DateNatives_timeZoneName"; 488 native "DateNatives_timeZoneName";
486 489
487 static int _timeZoneOffsetInSecondsForClampedSeconds(int secondsSinceEpoch) 490 static int _timeZoneOffsetInSecondsForClampedSeconds(int secondsSinceEpoch)
488 native "DateNatives_timeZoneOffsetInSeconds"; 491 native "DateNatives_timeZoneOffsetInSeconds";
489 492
490 static int _localTimeZoneAdjustmentInSeconds() 493 static int _localTimeZoneAdjustmentInSeconds()
491 native "DateNatives_localTimeZoneAdjustmentInSeconds"; 494 native "DateNatives_localTimeZoneAdjustmentInSeconds";
492 } 495 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698