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

Unified 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: 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 side-by-side diff with in-line comments
Download patch
Index: runtime/lib/date.dart
diff --git a/runtime/lib/date.dart b/runtime/lib/date.dart
index 71c079fa7b6e40c1ed5d2b10b0efce6c3a5cc51a..6a3dfb724f7a4e2a972a6b5d60c31f359ba9b964 100644
--- a/runtime/lib/date.dart
+++ b/runtime/lib/date.dart
@@ -7,7 +7,7 @@
class DateImplementation implements Date {
static final int _MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
- DateImplementation(int years,
+ DateImplementation(int year,
[int month = 1,
int day = 1,
int hour = 0,
@@ -17,7 +17,7 @@ class DateImplementation implements Date {
bool isUtc = false])
: this.isUtc = isUtc,
this.millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
- years, month, day, hour, minute, second, millisecond, isUtc) {
+ year, month, day, hour, minute, second, millisecond, isUtc) {
if (millisecondsSinceEpoch === null) throw new IllegalArgumentException();
if (isUtc === null) throw new IllegalArgumentException();
}
@@ -54,7 +54,7 @@ class DateImplementation implements Date {
return Math.parseDouble(matched);
}
- int years = Math.parseInt(match[1]);
+ int year = Math.parseInt(match[1]);
int month = Math.parseInt(match[2]);
int day = Math.parseInt(match[3]);
int hour = parseIntOrZero(match[4]);
@@ -69,7 +69,7 @@ class DateImplementation implements Date {
// TODO(floitsch): we should not need to test against the empty string.
bool isUtc = (match[8] !== null) && (match[8] != "");
int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
- years, month, day, hour, minute, second, millisecond, isUtc);
+ year, month, day, hour, minute, second, millisecond, isUtc);
if (millisecondsSinceEpoch === null) {
throw new IllegalArgumentException(formattedString);
}
@@ -246,8 +246,8 @@ class DateImplementation implements Date {
/** The first list contains the days until each month in non-leap years. The
* second list contains the days in leap years. */
static final List<List<int>> _DAYS_UNTIL_MONTH =
- const [const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
- const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]];
+ const [const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365],
+ const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366]];
floitsch 2012/08/06 21:00:58 80chars.
dominich 2012/08/06 21:20:58 Done.
// Returns the UTC year, month and day for the corresponding
// [millisecondsSinceEpoch].
@@ -340,23 +340,53 @@ class DateImplementation implements Date {
}
static _brokenDownDateToMillisecondsSinceEpoch(
- int years, int month, int day,
+ int year, int month, int day,
int hour, int minute, int second, int millisecond,
bool isUtc) {
- if ((month < 1) || (month > 12)) return null;
- if ((day < 1) || (day > 31)) return null;
- // Leap seconds can lead to hour == 24.
- if ((hour < 0) || (hour > 24)) return null;
- if ((hour == 24) && ((minute != 0) || (second != 0))) return null;
- if ((minute < 0) || (minute > 59)) return null;
- if ((second < 0) || (second > 59)) return null;
- if ((millisecond < 0) || (millisecond > 999)) return null;
+ // Deal with under and overflow.
+ second += (millisecond / 1000).floor().toInt();
+ millisecond = millisecond % 1000;
+ minute += (second / 60).floor().toInt();
+ second = second % 60;
+ hour += (minute / 60).floor().toInt();
+ minute = minute % 60;
+ day += (hour / 24).floor().toInt();
+ hour = hour % 24;
+ year += ((month - 1) / 12).floor().toInt();
+ month = (month - 1) % 12 + 1;
+
+ // Start with the current month and add _DAYS_UNTIL_MONTH until day > 1
+ // (and <= numDaysInMonth).
+ while (day < 1) {
+ int numDaysInMonth = _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month] -
+ _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month - 1];
+ day += numDaysInMonth;
+ --month;
+ if (month < 1) {
+ --year;
+ month = 12;
+ }
+ }
+
+ // And in reverse.
+ int numDaysInMonth = _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month] -
+ _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month - 1];
+ while (day > numDaysInMonth) {
+ day -= numDaysInMonth;
+ ++month;
+ if (month > 12) {
+ ++year;
+ month = 1;
+ }
+ numDaysInMonth = _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month] -
+ _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month - 1];
+ }
// First compute the seconds in UTC, independent of the [isUtc] flag. If
// necessary we will add the time-zone offset later on.
int days = day - 1;
- days += _DAYS_UNTIL_MONTH[_isLeapYear(years) ? 1 : 0][month - 1];
floitsch 2012/08/06 21:00:58 Isn't it enough to: years += (month - 1) ~/ 12; in
dominich 2012/08/06 21:20:58 No - clampedMonth could be -50 in which case years
floitsch 2012/08/07 09:10:07 I don't see how this could happen since it is .rem
dominich 2012/08/13 19:26:35 i've just realised - i'm not sure which bit of the
floitsch 2012/08/13 19:41:34 Unless I'm wrong you don't need to do any loops. T
- days += _dayFromYear(years);
+ days += _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month - 1];
+ days += _dayFromYear(year);
int millisecondsSinceEpoch = days * Duration.MILLISECONDS_PER_DAY +
hour * Duration.MILLISECONDS_PER_HOUR +
minute * Duration.MILLISECONDS_PER_MINUTE+

Powered by Google App Engine
This is Rietveld 408576698