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+ |