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

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

Issue 10538105: Make isUtc a getter, change some method names in Date. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 6 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
« no previous file with comments | « runtime/bin/timer_impl.dart ('k') | samples/chat/chat_server_lib.dart » ('j') | 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) 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_VALUE = 8640000000000000; 8 static final int _MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
9 9
10 DateImplementation(int years, 10 DateImplementation(int years,
11 [int month = 1, 11 [int month = 1,
12 int day = 1, 12 int day = 1,
13 int hours = 0, 13 int hour = 0,
14 int minutes = 0, 14 int minute = 0,
15 int seconds = 0, 15 int second = 0,
16 int milliseconds = 0, 16 int millisecond = 0,
17 bool isUtc = false]) 17 bool isUtc = false])
18 : _isUtc = isUtc, 18 : this.isUtc = isUtc,
19 value = _brokenDownDateToMillisecondsSinceEpoch( 19 this.millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
20 years, month, day, hours, minutes, seconds, milliseconds, isUtc) { 20 years, month, day, hour, minute, second, millisecond, isUtc) {
21 if (value === null) throw new IllegalArgumentException(); 21 if (millisecondsSinceEpoch === null) throw new IllegalArgumentException();
22 if (isUtc === null) throw new IllegalArgumentException();
22 } 23 }
23 24
24 DateImplementation.now() 25 DateImplementation.now()
25 : _isUtc = false, 26 : isUtc = false,
26 value = _getCurrentMs() { 27 millisecondsSinceEpoch = _getCurrentMs() {
27 } 28 }
28 29
29 factory DateImplementation.fromString(String formattedString) { 30 factory DateImplementation.fromString(String formattedString) {
30 // Read in (a subset of) ISO 8601. 31 // Read in (a subset of) ISO 8601.
31 // Examples: 32 // Examples:
32 // - "2012-02-27 13:27:00" 33 // - "2012-02-27 13:27:00"
33 // - "2012-02-27 13:27:00.423z" 34 // - "2012-02-27 13:27:00.423z"
34 // - "20120227 13:27:00" 35 // - "20120227 13:27:00"
35 // - "20120227T132700" 36 // - "20120227T132700"
36 // - "20120227" 37 // - "20120227"
(...skipping 12 matching lines...) Expand all
49 50
50 double parseDoubleOrZero(String matched) { 51 double parseDoubleOrZero(String matched) {
51 // 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.
52 if (matched === null || matched == "") return 0.0; 53 if (matched === null || matched == "") return 0.0;
53 return Math.parseDouble(matched); 54 return Math.parseDouble(matched);
54 } 55 }
55 56
56 int years = Math.parseInt(match[1]); 57 int years = Math.parseInt(match[1]);
57 int month = Math.parseInt(match[2]); 58 int month = Math.parseInt(match[2]);
58 int day = Math.parseInt(match[3]); 59 int day = Math.parseInt(match[3]);
59 int hours = parseIntOrZero(match[4]); 60 int hour = parseIntOrZero(match[4]);
60 int minutes = parseIntOrZero(match[5]); 61 int minute = parseIntOrZero(match[5]);
61 int seconds = parseIntOrZero(match[6]); 62 int second = parseIntOrZero(match[6]);
62 bool addOneMillisecond = false; 63 bool addOneMillisecond = false;
63 int milliseconds = (parseDoubleOrZero(match[7]) * 1000).round().toInt(); 64 int millisecond = (parseDoubleOrZero(match[7]) * 1000).round().toInt();
64 if (milliseconds == 1000) { 65 if (millisecond == 1000) {
65 addOneMillisecond = true; 66 addOneMillisecond = true;
66 milliseconds = 999; 67 millisecond = 999;
67 } 68 }
68 // 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.
69 bool isUtc = (match[8] !== null) && (match[8] != ""); 70 bool isUtc = (match[8] !== null) && (match[8] != "");
70 int epochValue = _brokenDownDateToMillisecondsSinceEpoch( 71 int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
71 years, month, day, hours, minutes, seconds, milliseconds, isUtc); 72 years, month, day, hour, minute, second, millisecond, isUtc);
72 if (epochValue === null) { 73 if (millisecondsSinceEpoch === null) {
73 throw new IllegalArgumentException(formattedString); 74 throw new IllegalArgumentException(formattedString);
74 } 75 }
75 if (addOneMillisecond) epochValue++; 76 if (addOneMillisecond) millisecondsSinceEpoch++;
76 return new DateImplementation.fromEpoch(epochValue, isUtc); 77 return new DateImplementation.fromMillisecondsSinceEpoch(
78 millisecondsSinceEpoch, isUtc);
77 } else { 79 } else {
78 throw new IllegalArgumentException(formattedString); 80 throw new IllegalArgumentException(formattedString);
79 } 81 }
80 } 82 }
81 83
82 DateImplementation.fromEpoch(int this.value, [bool isUtc = false]) 84 DateImplementation.fromMillisecondsSinceEpoch(
83 : _isUtc = isUtc { 85 int this.millisecondsSinceEpoch, [bool isUtc = false])
84 if (value.abs() > _MAX_VALUE) throw new IllegalArgumentException(value); 86 : this.isUtc = isUtc {
87 if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH) {
88 throw new IllegalArgumentException(millisecondsSinceEpoch);
89 }
90 if (isUtc === null) {
91 throw new IllegalArgumentException(isUtc);
92 }
85 } 93 }
86 94
87 bool operator ==(Object other) { 95 bool operator ==(Object other) {
88 if (other is !DateImplementation) return false; 96 if (other is !DateImplementation) return false;
89 DateImplementation otherDate = other; 97 DateImplementation otherDate = other;
90 return value == otherDate.value; 98 return millisecondsSinceEpoch == otherDate.millisecondsSinceEpoch;
91 } 99 }
92 100
93 bool operator <(Date other) => value < other.value; 101 bool operator <(Date other)
102 => millisecondsSinceEpoch < other.millisecondsSinceEpoch;
94 103
95 bool operator <=(Date other) => value <= other.value; 104 bool operator <=(Date other)
105 => millisecondsSinceEpoch <= other.millisecondsSinceEpoch;
96 106
97 bool operator >(Date other) => value > other.value; 107 bool operator >(Date other)
108 => millisecondsSinceEpoch > other.millisecondsSinceEpoch;
98 109
99 bool operator >=(Date other) => value >= other.value; 110 bool operator >=(Date other)
111 => millisecondsSinceEpoch >= other.millisecondsSinceEpoch;
100 112
101 int compareTo(Date other) => value.compareTo(other.value); 113 int compareTo(Date other)
102 int hashCode() => value; 114 => millisecondsSinceEpoch.compareTo(other.millisecondsSinceEpoch);
115
116 int hashCode() => millisecondsSinceEpoch;
103 117
104 Date toLocal() { 118 Date toLocal() {
105 if (isUtc()) return new DateImplementation.fromEpoch(value, false); 119 if (isUtc) {
120 return new DateImplementation.fromMillisecondsSinceEpoch(
121 millisecondsSinceEpoch, false);
122 }
106 return this; 123 return this;
107 } 124 }
108 125
109 Date toUtc() { 126 Date toUtc() {
110 if (isUtc()) return this; 127 if (isUtc) return this;
111 return new DateImplementation.fromEpoch(value, true); 128 return new DateImplementation.fromMillisecondsSinceEpoch(
129 millisecondsSinceEpoch, true);
112 } 130 }
113 131
114 String get timeZoneName() { 132 String get timeZoneName() {
115 if (isUtc()) return "UTC"; 133 if (isUtc) return "UTC";
116 return _timeZoneName(value); 134 return _timeZoneName(millisecondsSinceEpoch);
117 } 135 }
118 136
119 Duration get timeZoneOffset() { 137 Duration get timeZoneOffset() {
120 if (isUtc()) return new Duration(0); 138 if (isUtc) return new Duration(0);
121 int offsetInSeconds = _timeZoneOffsetInSeconds(value); 139 int offsetInSeconds = _timeZoneOffsetInSeconds(millisecondsSinceEpoch);
122 return new Duration(seconds: offsetInSeconds); 140 return new Duration(seconds: offsetInSeconds);
123 } 141 }
124 142
125 int get year() { 143 int get year() {
126 return _decomposeIntoYearMonthDay(_localDateInUtcValue)[0]; 144 return _decomposeIntoYearMonthDay(_localDateInUtcMs)[0];
127 } 145 }
128 146
129 int get month() { 147 int get month() {
130 return _decomposeIntoYearMonthDay(_localDateInUtcValue)[1]; 148 return _decomposeIntoYearMonthDay(_localDateInUtcMs)[1];
131 } 149 }
132 150
133 int get day() { 151 int get day() {
134 return _decomposeIntoYearMonthDay(_localDateInUtcValue)[2]; 152 return _decomposeIntoYearMonthDay(_localDateInUtcMs)[2];
135 } 153 }
136 154
137 int get hours() { 155 int get hour() {
138 int valueInHours = _flooredDivision(_localDateInUtcValue, 156 int valueInHours = _flooredDivision(_localDateInUtcMs,
139 Duration.MILLISECONDS_PER_HOUR); 157 Duration.MILLISECONDS_PER_HOUR);
140 return valueInHours % Duration.HOURS_PER_DAY; 158 return valueInHours % Duration.HOURS_PER_DAY;
141 } 159 }
142 160
143 int get minutes() { 161 int get minute() {
144 int valueInMinutes = _flooredDivision(_localDateInUtcValue, 162 int valueInMinutes = _flooredDivision(_localDateInUtcMs,
145 Duration.MILLISECONDS_PER_MINUTE); 163 Duration.MILLISECONDS_PER_MINUTE);
146 return valueInMinutes % Duration.MINUTES_PER_HOUR; 164 return valueInMinutes % Duration.MINUTES_PER_HOUR;
147 } 165 }
148 166
149 int get seconds() { 167 int get second() {
150 // Seconds are unaffected by the timezone the user is in. So we can 168 // Seconds are unaffected by the timezone the user is in. So we can
151 // directly use the value and not the [_localDateInUtcValue]. 169 // directly use the millisecondsSinceEpoch and not [_localDateInUtcMs].
152 int valueInSeconds = 170 int valueInSeconds =
153 _flooredDivision(value, Duration.MILLISECONDS_PER_SECOND); 171 _flooredDivision(millisecondsSinceEpoch,
172 Duration.MILLISECONDS_PER_SECOND);
154 return valueInSeconds % Duration.SECONDS_PER_MINUTE; 173 return valueInSeconds % Duration.SECONDS_PER_MINUTE;
155 } 174 }
156 175
157 int get milliseconds() { 176 int get millisecond() {
158 // Milliseconds are unaffected by the timezone the user is in. So we can 177 // Milliseconds are unaffected by the timezone the user is in. So we can
159 // directly use the value and not the [_localDateInUtcValue]. 178 // directly use the value and not the [_localDateInUtcValue].
160 return value % Duration.MILLISECONDS_PER_SECOND; 179 return millisecondsSinceEpoch % Duration.MILLISECONDS_PER_SECOND;
161 } 180 }
162 181
182 /** Returns the weekday of [this]. In accordance with ISO 8601 a week
183 * starts with Monday. Monday has the value 1 up to Sunday with 7. */
163 int get weekday() { 184 int get weekday() {
164 int daysSince1970 = 185 int daysSince1970 =
165 _flooredDivision(_localDateInUtcValue, Duration.MILLISECONDS_PER_DAY); 186 _flooredDivision(_localDateInUtcMs, Duration.MILLISECONDS_PER_DAY);
166 // 1970-1-1 was a Thursday. 187 // 1970-1-1 was a Thursday.
167 return ((daysSince1970 + Date.THU) % Date.DAYS_IN_WEEK); 188 return ((daysSince1970 + Date.THU - Date.MON) % Date.DAYS_IN_WEEK) +
189 Date.MON;
168 } 190 }
169 191
170 bool isUtc() => _isUtc;
171
172 String toString() { 192 String toString() {
173 String fourDigits(int n) { 193 String fourDigits(int n) {
174 int absN = n.abs(); 194 int absN = n.abs();
175 String sign = n < 0 ? "-" : ""; 195 String sign = n < 0 ? "-" : "";
176 if (absN >= 1000) return "$n"; 196 if (absN >= 1000) return "$n";
177 if (absN >= 100) return "${sign}0$absN"; 197 if (absN >= 100) return "${sign}0$absN";
178 if (absN >= 10) return "${sign}00$absN"; 198 if (absN >= 10) return "${sign}00$absN";
179 if (absN >= 1) return "${sign}000$absN"; 199 if (absN >= 1) return "${sign}000$absN";
180 } 200 }
181 String threeDigits(int n) { 201 String threeDigits(int n) {
182 if (n >= 100) return "${n}"; 202 if (n >= 100) return "${n}";
183 if (n >= 10) return "0${n}"; 203 if (n >= 10) return "0${n}";
184 return "00${n}"; 204 return "00${n}";
185 } 205 }
186 String twoDigits(int n) { 206 String twoDigits(int n) {
187 if (n >= 10) return "${n}"; 207 if (n >= 10) return "${n}";
188 return "0${n}"; 208 return "0${n}";
189 } 209 }
190 210
191 String y = fourDigits(year); 211 String y = fourDigits(year);
192 String m = twoDigits(month); 212 String m = twoDigits(month);
193 String d = twoDigits(day); 213 String d = twoDigits(day);
194 String h = twoDigits(hours); 214 String h = twoDigits(hour);
195 String min = twoDigits(minutes); 215 String min = twoDigits(minute);
196 String sec = twoDigits(seconds); 216 String sec = twoDigits(second);
197 String ms = threeDigits(milliseconds); 217 String ms = threeDigits(millisecond);
198 if (isUtc()) { 218 if (isUtc) {
199 return "$y-$m-$d $h:$min:$sec.${ms}Z"; 219 return "$y-$m-$d $h:$min:$sec.${ms}Z";
200 } else { 220 } else {
201 return "$y-$m-$d $h:$min:$sec.$ms"; 221 return "$y-$m-$d $h:$min:$sec.$ms";
202 } 222 }
203 } 223 }
204 224
205 /** Returns a new [Date] with the [duration] added to [this]. */ 225 /** Returns a new [Date] with the [duration] added to [this]. */
206 Date add(Duration duration) { 226 Date add(Duration duration) {
207 return new DateImplementation.fromEpoch(value + duration.inMilliseconds, 227 int ms = millisecondsSinceEpoch;
208 isUtc()); 228 return new DateImplementation.fromMillisecondsSinceEpoch(
229 ms + duration.inMilliseconds, isUtc);
209 } 230 }
210 231
211 /** Returns a new [Date] with the [duration] subtracted from [this]. */ 232 /** Returns a new [Date] with the [duration] subtracted from [this]. */
212 Date subtract(Duration duration) { 233 Date subtract(Duration duration) {
213 return new DateImplementation.fromEpoch(value - duration.inMilliseconds, 234 int ms = millisecondsSinceEpoch;
214 isUtc()); 235 return new DateImplementation.fromMillisecondsSinceEpoch(
236 ms - duration.inMilliseconds, isUtc);
215 } 237 }
216 238
217 /** Returns a [Duration] with the difference of [this] and [other]. */ 239 /** Returns a [Duration] with the difference of [this] and [other]. */
218 Duration difference(Date other) { 240 Duration difference(Date other) {
219 return new DurationImplementation(milliseconds: value - other.value); 241 int ms = millisecondsSinceEpoch;
242 int otherMs = other.millisecondsSinceEpoch;
243 return new DurationImplementation(milliseconds: ms - otherMs);
220 } 244 }
221 245
222 /** The first list contains the days until each month in non-leap years. The 246 /** The first list contains the days until each month in non-leap years. The
223 * second list contains the days in leap years. */ 247 * second list contains the days in leap years. */
224 static final List<List<int>> _DAYS_UNTIL_MONTH = 248 static final List<List<int>> _DAYS_UNTIL_MONTH =
225 const [const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334], 249 const [const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
226 const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]]; 250 const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]];
227 251
228 // Returns the UTC year, month and day for the corresponding 252 // Returns the UTC year, month and day for the corresponding
229 // [millisecondsSinceEpoch]. 253 // [millisecondsSinceEpoch].
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 for (resultMonth = 12; 292 for (resultMonth = 12;
269 daysUntilMonth[resultMonth - 1] > days; 293 daysUntilMonth[resultMonth - 1] > days;
270 resultMonth--) { 294 resultMonth--) {
271 // Do nothing. 295 // Do nothing.
272 } 296 }
273 resultDay = days - daysUntilMonth[resultMonth - 1] + 1; 297 resultDay = days - daysUntilMonth[resultMonth - 1] + 1;
274 return <int>[resultYear, resultMonth, resultDay]; 298 return <int>[resultYear, resultMonth, resultDay];
275 } 299 }
276 300
277 /** 301 /**
278 * Returns the amount of milliseconds in UTC that represent the same values as 302 * Returns the amount of milliseconds in UTC that represent the same values
279 * [this]. 303 * as [this].
280 * 304 *
281 * Say [:t:] is the result of this function, then 305 * Say [:t:] is the result of this function, then
282 * * [:this.year == new Date.fromEpoch(t, isUtc: true).year:], 306 * * [:this.year == new Date.fromMillisecondsSinceEpoch(t, true).year:],
283 * * [:this.month == new Date.fromEpoch(t, isUtc: true).month:], 307 * * [:this.month == new Date.fromMillisecondsSinceEpoch(t, true).month:],
284 * * [:this.day == new Date.fromEpoch(t, isUtc: true).day:], 308 * * [:this.day == new Date.fromMillisecondsSinceEpoch(t, true).day:],
285 * * [:this.hours == new Date.fromEpoch(t, isUtc: true).hours:], 309 * * [:this.hour == new Date.fromMillisecondsSinceEpoch(t, true).hour:],
286 * * ... 310 * * ...
287 * 311 *
288 * Daylight savings is computed as if the date was computed in [1970..2037]. 312 * Daylight savings is computed as if the date was computed in [1970..2037].
289 * If [this] lies outside this range then it is a year with similar properties 313 * If [this] lies outside this range then it is a year with similar
290 * (leap year, weekdays) is used instead. 314 * properties (leap year, weekdays) is used instead.
291 */ 315 */
292 int get _localDateInUtcValue() { 316 int get _localDateInUtcMs() {
293 if (isUtc()) return value; 317 int ms = millisecondsSinceEpoch;
318 if (isUtc) return ms;
294 int offset = 319 int offset =
295 _timeZoneOffsetInSeconds(value) * Duration.MILLISECONDS_PER_SECOND; 320 _timeZoneOffsetInSeconds(ms) * Duration.MILLISECONDS_PER_SECOND;
296 return value + offset; 321 return ms + offset;
297 } 322 }
298 323
299 static int _flooredDivision(int a, int b) { 324 static int _flooredDivision(int a, int b) {
300 return (a - (a < 0 ? b - 1 : 0)) ~/ b; 325 return (a - (a < 0 ? b - 1 : 0)) ~/ b;
301 } 326 }
302 327
303 // 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].
304 // [year] may be before epoch. 329 // [year] may be before epoch.
305 static int _dayFromYear(int year) { 330 static int _dayFromYear(int year) {
306 return 365 * (year - 1970) 331 return 365 * (year - 1970)
307 + _flooredDivision(year - 1969, 4) 332 + _flooredDivision(year - 1969, 4)
308 - _flooredDivision(year - 1901, 100) 333 - _flooredDivision(year - 1901, 100)
309 + _flooredDivision(year - 1601, 400); 334 + _flooredDivision(year - 1601, 400);
310 } 335 }
311 336
312 static bool _isLeapYear(y) { 337 static bool _isLeapYear(y) {
313 return (y.remainder(4) == 0) && 338 return (y.remainder(4) == 0) &&
314 ((y.remainder(100) != 0) || (y.remainder(400) == 0)); 339 ((y.remainder(100) != 0) || (y.remainder(400) == 0));
315 } 340 }
316 341
317 static _brokenDownDateToMillisecondsSinceEpoch( 342 static _brokenDownDateToMillisecondsSinceEpoch(
318 int years, int month, int day, 343 int years, int month, int day,
319 int hours, int minutes, int seconds, int milliseconds, 344 int hour, int minute, int second, int millisecond,
320 bool isUtc) { 345 bool isUtc) {
321 if ((month < 1) || (month > 12)) return null; 346 if ((month < 1) || (month > 12)) return null;
322 if ((day < 1) || (day > 31)) return null; 347 if ((day < 1) || (day > 31)) return null;
323 // Leap seconds can lead to hours == 24. 348 // Leap seconds can lead to hour == 24.
324 if ((hours < 0) || (hours > 24)) return null; 349 if ((hour < 0) || (hour > 24)) return null;
325 if ((hours == 24) && ((minutes != 0) || (seconds != 0))) return null; 350 if ((hour == 24) && ((minute != 0) || (second != 0))) return null;
326 if ((minutes < 0) || (minutes > 59)) return null; 351 if ((minute < 0) || (minute > 59)) return null;
327 if ((seconds < 0) || (seconds > 59)) return null; 352 if ((second < 0) || (second > 59)) return null;
328 if ((milliseconds < 0) || (milliseconds > 999)) return null; 353 if ((millisecond < 0) || (millisecond > 999)) return null;
329 354
330 // First compute the seconds in UTC, independent of the [isUtc] flag. If 355 // First compute the seconds in UTC, independent of the [isUtc] flag. If
331 // necessary we will add the time-zone offset later on. 356 // necessary we will add the time-zone offset later on.
332 int days = day - 1; 357 int days = day - 1;
333 days += _DAYS_UNTIL_MONTH[_isLeapYear(years) ? 1 : 0][month - 1]; 358 days += _DAYS_UNTIL_MONTH[_isLeapYear(years) ? 1 : 0][month - 1];
334 days += _dayFromYear(years); 359 days += _dayFromYear(years);
335 int millisecondsSinceEpoch = days * Duration.MILLISECONDS_PER_DAY + 360 int millisecondsSinceEpoch = days * Duration.MILLISECONDS_PER_DAY +
336 hours * Duration.MILLISECONDS_PER_HOUR + 361 hour * Duration.MILLISECONDS_PER_HOUR +
337 minutes * Duration.MILLISECONDS_PER_MINUTE+ 362 minute * Duration.MILLISECONDS_PER_MINUTE+
338 seconds * Duration.MILLISECONDS_PER_SECOND + 363 second * Duration.MILLISECONDS_PER_SECOND +
339 milliseconds; 364 millisecond;
340 365
341 // Since [_timeZoneOffsetInSeconds] will crash if the input is far out of 366 // Since [_timeZoneOffsetInSeconds] will crash if the input is far out of
342 // the valid range we do a preliminary test that weeds out values that can 367 // the valid range we do a preliminary test that weeds out values that can
343 // not become valid even with timezone adjustments. 368 // not become valid even with timezone adjustments.
344 // The timezone adjustment is always less than a day, so adding a security 369 // The timezone adjustment is always less than a day, so adding a security
345 // margin of one day should be enough. 370 // margin of one day should be enough.
346 if (millisecondsSinceEpoch.abs() > 371 if (millisecondsSinceEpoch.abs() >
347 (_MAX_VALUE + Duration.MILLISECONDS_PER_DAY)) { 372 (_MAX_MILLISECONDS_SINCE_EPOCH + Duration.MILLISECONDS_PER_DAY)) {
348 return null; 373 return null;
349 } 374 }
350 375
351 if (!isUtc) { 376 if (!isUtc) {
352 // Note that we need to remove the local timezone adjustement before 377 // Note that we need to remove the local timezone adjustement before
353 // asking for the correct zone offset. 378 // asking for the correct zone offset.
354 int adjustment = _localTimeZoneAdjustmentInSeconds() * 379 int adjustment = _localTimeZoneAdjustmentInSeconds() *
355 Duration.MILLISECONDS_PER_SECOND; 380 Duration.MILLISECONDS_PER_SECOND;
356 int zoneOffset = 381 int zoneOffset =
357 _timeZoneOffsetInSeconds(millisecondsSinceEpoch - adjustment); 382 _timeZoneOffsetInSeconds(millisecondsSinceEpoch - adjustment);
358 millisecondsSinceEpoch -= zoneOffset * Duration.MILLISECONDS_PER_SECOND; 383 millisecondsSinceEpoch -= zoneOffset * Duration.MILLISECONDS_PER_SECOND;
359 } 384 }
360 if (millisecondsSinceEpoch.abs() > _MAX_VALUE) return null; 385 if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH) {
386 return null;
387 }
361 return millisecondsSinceEpoch; 388 return millisecondsSinceEpoch;
362 } 389 }
363 390
364 /** 391 /**
365 * Returns a year in the range 2008-2035 matching 392 * Returns a year in the range 2008-2035 matching
366 * * leap year, and 393 * * leap year, and
367 * * week day of first day. 394 * * week day of first day.
368 * 395 *
369 * Leap seconds are ignored. 396 * Leap seconds are ignored.
370 * Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9. 397 * Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 static int _timeZoneOffsetInSeconds(int millisecondsSinceEpoch) { 468 static int _timeZoneOffsetInSeconds(int millisecondsSinceEpoch) {
442 int equivalentSeconds = _equivalentSeconds(millisecondsSinceEpoch); 469 int equivalentSeconds = _equivalentSeconds(millisecondsSinceEpoch);
443 return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds); 470 return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds);
444 } 471 }
445 472
446 static String _timeZoneName(int millisecondsSinceEpoch) { 473 static String _timeZoneName(int millisecondsSinceEpoch) {
447 int equivalentSeconds = _equivalentSeconds(millisecondsSinceEpoch); 474 int equivalentSeconds = _equivalentSeconds(millisecondsSinceEpoch);
448 return _timeZoneNameForClampedSeconds(equivalentSeconds); 475 return _timeZoneNameForClampedSeconds(equivalentSeconds);
449 } 476 }
450 477
451 final bool _isUtc; 478 final bool isUtc;
452 final int value; 479 final int millisecondsSinceEpoch;
453 480
454 // Natives 481 // Natives
455 static int _getCurrentMs() native "DateNatives_currentTimeMillis"; 482 static int _getCurrentMs() native "DateNatives_currentTimeMillis";
456 483
457 static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch) 484 static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch)
458 native "DateNatives_timeZoneName"; 485 native "DateNatives_timeZoneName";
459 486
460 static int _timeZoneOffsetInSecondsForClampedSeconds(int secondsSinceEpoch) 487 static int _timeZoneOffsetInSecondsForClampedSeconds(int secondsSinceEpoch)
461 native "DateNatives_timeZoneOffsetInSeconds"; 488 native "DateNatives_timeZoneOffsetInSeconds";
462 489
463 static int _localTimeZoneAdjustmentInSeconds() 490 static int _localTimeZoneAdjustmentInSeconds()
464 native "DateNatives_localTimeZoneAdjustmentInSeconds"; 491 native "DateNatives_localTimeZoneAdjustmentInSeconds";
465 } 492 }
OLDNEW
« no previous file with comments | « runtime/bin/timer_impl.dart ('k') | samples/chat/chat_server_lib.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698