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

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

Issue 10411057: Deprecate use of timezones. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix code using old api. Created 8 years, 7 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 class TimeZoneImplementation implements TimeZone { 6 class TimeZoneImplementation implements TimeZone {
7 const TimeZoneImplementation.utc() : isUtc = true; 7 const TimeZoneImplementation.utc() : isUtc = true;
8 TimeZoneImplementation.local() : isUtc = false {} 8 TimeZoneImplementation.local() : isUtc = false {}
9 9
10 bool operator ==(Object other) { 10 bool operator ==(Object other) {
11 if (!(other is TimeZoneImplementation)) return false; 11 if (!(other is TimeZoneImplementation)) return false;
12 return isUtc == other.isUtc; 12 return isUtc == other.isUtc;
13 } 13 }
14 14
15 final bool isUtc; 15 final bool isUtc;
16 } 16 }
17 17
18 // JavaScript implementation of DateImplementation. 18 // VM implementation of DateImplementation.
19 class DateImplementation implements Date { 19 class DateImplementation implements Date {
20 factory DateImplementation(int years, 20 static final int _SECONDS_YEAR_2035 = 2051222400;
21 [int month = 1, 21
22 int day = 1, 22 DateImplementation(int years,
23 int hours = 0, 23 [int month = 1,
24 int minutes = 0, 24 int day = 1,
25 int seconds = 0, 25 int hours = 0,
26 int milliseconds = 0]) { 26 int minutes = 0,
27 return new DateImplementation.withTimeZone( 27 int seconds = 0,
28 years, month, day, 28 int milliseconds = 0,
29 hours, minutes, seconds, milliseconds, 29 bool isUtc = false])
30 new TimeZoneImplementation.local()); 30 : _isUtc = isUtc,
31 value = _brokenDownDateToMillisecondsSinceEpoch(
32 years, month, day, hours, minutes, seconds, milliseconds, isUtc) {
33 if (value === null) throw new IllegalArgumentException();
31 } 34 }
32 35
33 DateImplementation.withTimeZone(int years, 36 DateImplementation.withTimeZone(int years,
34 int month, 37 int month,
35 int day, 38 int day,
36 int hours, 39 int hours,
37 int minutes, 40 int minutes,
38 int seconds, 41 int seconds,
39 int milliseconds, 42 int milliseconds,
40 TimeZone timeZone) 43 TimeZone timeZone)
41 : timeZone = timeZone, 44 : this(years, month, day, hours, minutes, seconds, milliseconds,
42 value = _brokenDownDateToMillisecondsSinceEpoch( 45 timeZone.isUtc);
43 years, month, day, hours, minutes, seconds, milliseconds,
44 timeZone.isUtc) {
45 if (value === null) throw new IllegalArgumentException();
46 }
47 46
48 DateImplementation.now() 47 DateImplementation.now()
49 : timeZone = new TimeZone.local(), 48 : _isUtc = true,
50 value = _getCurrentMs() { 49 value = _getCurrentMs() {
51 } 50 }
52 51
53 factory DateImplementation.fromString(String formattedString) { 52 factory DateImplementation.fromString(String formattedString) {
54 // Read in (a subset of) ISO 8601. 53 // Read in (a subset of) ISO 8601.
55 // Examples: 54 // Examples:
56 // - "2012-02-27 13:27:00" 55 // - "2012-02-27 13:27:00"
57 // - "2012-02-27 13:27:00.423z" 56 // - "2012-02-27 13:27:00.423z"
58 // - "20120227 13:27:00" 57 // - "20120227 13:27:00"
59 // - "20120227T132700" 58 // - "20120227T132700"
60 // - "20120227" 59 // - "20120227"
(...skipping 23 matching lines...) Expand all
84 int minutes = parseIntOrZero(match[5]); 83 int minutes = parseIntOrZero(match[5]);
85 int seconds = parseIntOrZero(match[6]); 84 int seconds = parseIntOrZero(match[6]);
86 bool addOneMillisecond = false; 85 bool addOneMillisecond = false;
87 int milliseconds = (parseDoubleOrZero(match[7]) * 1000).round().toInt(); 86 int milliseconds = (parseDoubleOrZero(match[7]) * 1000).round().toInt();
88 if (milliseconds == 1000) { 87 if (milliseconds == 1000) {
89 addOneMillisecond = true; 88 addOneMillisecond = true;
90 milliseconds = 999; 89 milliseconds = 999;
91 } 90 }
92 // TODO(floitsch): we should not need to test against the empty string. 91 // TODO(floitsch): we should not need to test against the empty string.
93 bool isUtc = (match[8] !== null) && (match[8] != ""); 92 bool isUtc = (match[8] !== null) && (match[8] != "");
94 TimeZone timezone = isUtc ? const TimeZone.utc() : new TimeZone.local();
95 int epochValue = _brokenDownDateToMillisecondsSinceEpoch( 93 int epochValue = _brokenDownDateToMillisecondsSinceEpoch(
96 years, month, day, hours, minutes, seconds, milliseconds, isUtc); 94 years, month, day, hours, minutes, seconds, milliseconds, isUtc);
97 if (epochValue === null) { 95 if (epochValue === null) {
98 throw new IllegalArgumentException(formattedString); 96 throw new IllegalArgumentException(formattedString);
99 } 97 }
100 if (addOneMillisecond) epochValue++; 98 if (addOneMillisecond) epochValue++;
101 return new DateImplementation.fromEpoch(epochValue, timezone); 99 return new DateImplementation.fromEpoch(epochValue, isUtc);
102 } else { 100 } else {
103 throw new IllegalArgumentException(formattedString); 101 throw new IllegalArgumentException(formattedString);
104 } 102 }
105 } 103 }
106 104
107 const DateImplementation.fromEpoch(int this.value, 105 DateImplementation.fromEpoch(int this.value, [bool isUtc = false])
108 TimeZone this.timeZone); 106 : _isUtc = isUtc;
109 107
110 bool operator ==(Object other) { 108 bool operator ==(Object other) {
111 if (!(other is DateImplementation)) return false; 109 if (other is !DateImplementation) return false;
112 return value == other.value && timeZone == other.timeZone; 110 return value == other.value;
113 } 111 }
114 112
115 bool operator <(Date other) => value < other.value; 113 bool operator <(Date other) => value < other.value;
116 114
117 bool operator <=(Date other) => value <= other.value; 115 bool operator <=(Date other) => value <= other.value;
118 116
119 bool operator >(Date other) => value > other.value; 117 bool operator >(Date other) => value > other.value;
120 118
121 bool operator >=(Date other) => value >= other.value; 119 bool operator >=(Date other) => value >= other.value;
122 120
123 int compareTo(Date other) => value.compareTo(other.value); 121 int compareTo(Date other) => value.compareTo(other.value);
124 int hashCode() => value; 122 int hashCode() => value;
125 123
124 Date toLocal() {
125 if (isUtc()) return new DateImplementation.fromEpoch(value, false);
126 return this;
127 }
128
129 Date toUtc() {
130 if (isUtc()) return this;
131 return new DateImplementation.fromEpoch(value, true);
132 }
133
126 Date changeTimeZone(TimeZone targetTimeZone) { 134 Date changeTimeZone(TimeZone targetTimeZone) {
127 if (targetTimeZone === null) { 135 if (targetTimeZone === null) {
128 targetTimeZone = new TimeZoneImplementation.local(); 136 targetTimeZone = new TimeZoneImplementation.local();
129 } 137 }
130 return new Date.fromEpoch(value, targetTimeZone); 138 return new Date.fromEpoch(value, targetTimeZone.isUtc);
131 } 139 }
132 140
133 String get timeZoneName() { 141 String get timeZoneName() {
134 if (isUtc()) return "UTC"; 142 if (isUtc()) return "UTC";
135 return _timeZoneName(_equivalentSeconds(_secondsSinceEpoch)); 143 return _timeZoneName(_equivalentSeconds(_secondsSinceEpoch));
136 } 144 }
137 145
138 Duration get timeZoneOffset() { 146 Duration get timeZoneOffset() {
139 if (isUtc()) return new Duration(0); 147 if (isUtc()) return new Duration(0);
140 int offsetInSeconds = 148 int offsetInSeconds =
141 _timeZoneOffsetInSeconds(_equivalentSeconds(_secondsSinceEpoch)); 149 _timeZoneOffsetInSeconds(_equivalentSeconds(_secondsSinceEpoch));
142 return new Duration(seconds: offsetInSeconds); 150 return new Duration(seconds: offsetInSeconds);
143 } 151 }
144 152
145 int get year() { 153 int get year() {
146 int secondsSinceEpoch = _secondsSinceEpoch; 154 int secondsSinceEpoch = _secondsSinceEpoch;
147 // According to V8 some library calls have troubles with negative values. 155 // According to V8 some library calls have troubles with negative values.
148 // Therefore clamp to 0 - year 2035 (which is less than the size of 32bit). 156 // Therefore clamp to 0 - year 2035 (which is less than the size of 32bit).
149 if (secondsSinceEpoch >= 0 && secondsSinceEpoch < _SECONDS_YEAR_2035) { 157 if (secondsSinceEpoch >= 0 && secondsSinceEpoch < _SECONDS_YEAR_2035) {
150 return _getYear(secondsSinceEpoch, timeZone.isUtc); 158 return _getYear(secondsSinceEpoch, isUtc());
151 } 159 }
152 160
153 // Approximate the result. We don't take timeZone into account. 161 // Approximate the result. We don't take timeZone into account.
154 int approximateYear = _yearsFromSecondsSinceEpoch(secondsSinceEpoch); 162 int approximateYear = _yearsFromSecondsSinceEpoch(secondsSinceEpoch);
155 int equivalentYear = _equivalentYear(approximateYear); 163 int equivalentYear = _equivalentYear(approximateYear);
156 int y = _getYear(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); 164 int y = _getYear(_equivalentSeconds(_secondsSinceEpoch), isUtc());
157 return approximateYear + (y - equivalentYear); 165 return approximateYear + (y - equivalentYear);
158 } 166 }
159 167
160 int get month() { 168 int get month() {
161 return _getMonth(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); 169 return _getMonth(_equivalentSeconds(_secondsSinceEpoch), isUtc());
162 } 170 }
163 171
164 int get day() { 172 int get day() {
165 return _getDay(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); 173 return _getDay(_equivalentSeconds(_secondsSinceEpoch), isUtc());
166 } 174 }
167 175
168 int get hours() { 176 int get hours() {
169 return _getHours(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); 177 return _getHours(_equivalentSeconds(_secondsSinceEpoch), isUtc());
170 } 178 }
171 179
172 int get minutes() { 180 int get minutes() {
173 return _getMinutes(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); 181 return _getMinutes(_equivalentSeconds(_secondsSinceEpoch), isUtc());
174 } 182 }
175 183
176 int get seconds() { 184 int get seconds() {
177 return _getSeconds(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); 185 return _getSeconds(_equivalentSeconds(_secondsSinceEpoch), isUtc());
178 } 186 }
179 187
180 int get milliseconds() { 188 int get milliseconds() {
181 return value % Duration.MILLISECONDS_PER_SECOND; 189 return value % Duration.MILLISECONDS_PER_SECOND;
182 } 190 }
183 191
184 int get _secondsSinceEpoch() { 192 int get _secondsSinceEpoch() {
185 // Always round down. 193 // Always round down.
186 if (value < 0) { 194 if (value < 0) {
187 return (value + 1) ~/ Duration.MILLISECONDS_PER_SECOND - 1; 195 return (value + 1) ~/ Duration.MILLISECONDS_PER_SECOND - 1;
188 } else { 196 } else {
189 return value ~/ Duration.MILLISECONDS_PER_SECOND; 197 return value ~/ Duration.MILLISECONDS_PER_SECOND;
190 } 198 }
191 } 199 }
192 200
193 int get weekday() { 201 int get weekday() {
194 final Date unixTimeStart = 202 final Date unixTimeStart = new Date(1970, 1, 1, 0, 0, 0, 0, isUtc());
195 new Date.withTimeZone(1970, 1, 1, 0, 0, 0, 0, timeZone);
196 int msSince1970 = this.difference(unixTimeStart).inMilliseconds; 203 int msSince1970 = this.difference(unixTimeStart).inMilliseconds;
197 // Adjust the milliseconds to avoid problems with summer-time. 204 // Adjust the milliseconds to avoid problems with summer-time.
198 if (hours < 2) { 205 if (hours < 2) {
199 msSince1970 += 2 * Duration.MILLISECONDS_PER_HOUR; 206 msSince1970 += 2 * Duration.MILLISECONDS_PER_HOUR;
200 } 207 }
201 // Compute the floor of msSince1970 / Duration.MS_PER_DAY. 208 // Compute the floor of msSince1970 / Duration.MS_PER_DAY.
202 int daysSince1970; 209 int daysSince1970;
203 if (msSince1970 >= 0) { 210 if (msSince1970 >= 0) {
204 daysSince1970 = msSince1970 ~/ Duration.MILLISECONDS_PER_DAY; 211 daysSince1970 = msSince1970 ~/ Duration.MILLISECONDS_PER_DAY;
205 } else { 212 } else {
206 daysSince1970 = (msSince1970 - Duration.MILLISECONDS_PER_DAY + 1) ~/ 213 daysSince1970 = (msSince1970 - Duration.MILLISECONDS_PER_DAY + 1) ~/
207 Duration.MILLISECONDS_PER_DAY; 214 Duration.MILLISECONDS_PER_DAY;
208 } 215 }
209 // 1970-1-1 was a Thursday. 216 // 1970-1-1 was a Thursday.
210 return ((daysSince1970 + Date.THU) % Date.DAYS_IN_WEEK); 217 return ((daysSince1970 + Date.THU) % Date.DAYS_IN_WEEK);
211 } 218 }
212 219
213 bool isLocalTime() { 220 bool isUtc() => _isUtc;
214 return !timeZone.isUtc;
215 }
216
217 bool isUtc() {
218 return timeZone.isUtc;
219 }
220 221
221 String toString() { 222 String toString() {
222 String fourDigits(int n) { 223 String fourDigits(int n) {
223 int absN = n.abs(); 224 int absN = n.abs();
224 String sign = n < 0 ? "-" : ""; 225 String sign = n < 0 ? "-" : "";
225 if (absN >= 1000) return "$n"; 226 if (absN >= 1000) return "$n";
226 if (absN >= 100) return "${sign}0$absN"; 227 if (absN >= 100) return "${sign}0$absN";
227 if (absN >= 10) return "${sign}00$absN"; 228 if (absN >= 10) return "${sign}00$absN";
228 if (absN >= 1) return "${sign}000$absN"; 229 if (absN >= 1) return "${sign}000$absN";
229 } 230 }
230 String threeDigits(int n) { 231 String threeDigits(int n) {
231 if (n >= 100) return "${n}"; 232 if (n >= 100) return "${n}";
232 if (n >= 10) return "0${n}"; 233 if (n >= 10) return "0${n}";
233 return "00${n}"; 234 return "00${n}";
234 } 235 }
235 String twoDigits(int n) { 236 String twoDigits(int n) {
236 if (n >= 10) return "${n}"; 237 if (n >= 10) return "${n}";
237 return "0${n}"; 238 return "0${n}";
238 } 239 }
239 240
240 String y = fourDigits(year); 241 String y = fourDigits(year);
241 String m = twoDigits(month); 242 String m = twoDigits(month);
242 String d = twoDigits(day); 243 String d = twoDigits(day);
243 String h = twoDigits(hours); 244 String h = twoDigits(hours);
244 String min = twoDigits(minutes); 245 String min = twoDigits(minutes);
245 String sec = twoDigits(seconds); 246 String sec = twoDigits(seconds);
246 String ms = threeDigits(milliseconds); 247 String ms = threeDigits(milliseconds);
247 if (timeZone.isUtc) { 248 if (isUtc()) {
248 return "$y-$m-$d $h:$min:$sec.${ms}Z"; 249 return "$y-$m-$d $h:$min:$sec.${ms}Z";
249 } else { 250 } else {
250 return "$y-$m-$d $h:$min:$sec.$ms"; 251 return "$y-$m-$d $h:$min:$sec.$ms";
251 } 252 }
252 } 253 }
253 254
254 // Adds the [duration] to this Date instance. 255 // Adds the [duration] to this Date instance.
255 Date add(Duration duration) { 256 Date add(Duration duration) {
256 return new DateImplementation.fromEpoch(value + duration.inMilliseconds, 257 return new DateImplementation.fromEpoch(value + duration.inMilliseconds,
257 timeZone); 258 isUtc());
258 } 259 }
259 260
260 // Subtracts the [duration] from this Date instance. 261 // Subtracts the [duration] from this Date instance.
261 Date subtract(Duration duration) { 262 Date subtract(Duration duration) {
262 return new DateImplementation.fromEpoch(value - duration.inMilliseconds, 263 return new DateImplementation.fromEpoch(value - duration.inMilliseconds,
263 timeZone); 264 isUtc());
264 } 265 }
265 266
266 // Returns a [Duration] with the difference of [this] and [other]. 267 // Returns a [Duration] with the difference of [this] and [other].
267 Duration difference(Date other) { 268 Duration difference(Date other) {
268 return new DurationImplementation(milliseconds: value - other.value); 269 return new DurationImplementation(milliseconds: value - other.value);
269 } 270 }
270 271
271 final int value;
272 final TimeZoneImplementation timeZone;
273
274 static final int _SECONDS_YEAR_2035 = 2051222400;
275
276 // Returns the UTC year for the corresponding [secondsSinceEpoch]. 272 // Returns the UTC year for the corresponding [secondsSinceEpoch].
277 // It is relatively fast for values in the range 0 to year 2098. 273 // It is relatively fast for values in the range 0 to year 2098.
278 // Code is adapted from V8. 274 // Code is adapted from V8.
279 static int _yearsFromSecondsSinceEpoch(int secondsSinceEpoch) { 275 static int _yearsFromSecondsSinceEpoch(int secondsSinceEpoch) {
280 final int DAYS_IN_4_YEARS = 4 * 365 + 1; 276 final int DAYS_IN_4_YEARS = 4 * 365 + 1;
281 final int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1; 277 final int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1;
282 final int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1; 278 final int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1;
283 final int DAYS_1970_TO_2000 = 30 * 365 + 7; 279 final int DAYS_1970_TO_2000 = 30 * 365 + 7;
284 final int DAYS_OFFSET = 1000 * DAYS_IN_400_YEARS + 5 * DAYS_IN_400_YEARS - 280 final int DAYS_OFFSET = 1000 * DAYS_IN_400_YEARS + 5 * DAYS_IN_400_YEARS -
285 DAYS_1970_TO_2000; 281 DAYS_1970_TO_2000;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 } else { 395 } else {
400 equivalentYear = years; 396 equivalentYear = years;
401 offsetInSeconds = 0; 397 offsetInSeconds = 0;
402 } 398 }
403 int secondsSinceEpoch = _brokenDownDateToSecondsSinceEpoch( 399 int secondsSinceEpoch = _brokenDownDateToSecondsSinceEpoch(
404 equivalentYear, month, day, hours, minutes, seconds, isUtc); 400 equivalentYear, month, day, hours, minutes, seconds, isUtc);
405 int adjustedSeconds = secondsSinceEpoch + offsetInSeconds; 401 int adjustedSeconds = secondsSinceEpoch + offsetInSeconds;
406 return adjustedSeconds * Duration.MILLISECONDS_PER_SECOND + milliseconds; 402 return adjustedSeconds * Duration.MILLISECONDS_PER_SECOND + milliseconds;
407 } 403 }
408 404
405 final bool _isUtc;
406 final int value;
407
408
409 // Natives 409 // Natives
410 static _brokenDownDateToSecondsSinceEpoch( 410 static _brokenDownDateToSecondsSinceEpoch(
411 int years, int month, int day, int hours, int minutes, int seconds, 411 int years, int month, int day, int hours, int minutes, int seconds,
412 bool isUtc) native "DateNatives_brokenDownToSecondsSinceEpoch"; 412 bool isUtc) native "DateNatives_brokenDownToSecondsSinceEpoch";
413 413
414 static int _getCurrentMs() native "DateNatives_currentTimeMillis"; 414 static int _getCurrentMs() native "DateNatives_currentTimeMillis";
415 415
416 static String _timeZoneName(int secondsSinceEpoch) 416 static String _timeZoneName(int secondsSinceEpoch)
417 native "DateNatives_timeZoneName"; 417 native "DateNatives_timeZoneName";
418 418
(...skipping 13 matching lines...) Expand all
432 432
433 static int _getHours(int secondsSinceEpoch, bool isUtc) 433 static int _getHours(int secondsSinceEpoch, bool isUtc)
434 native "DateNatives_getHours"; 434 native "DateNatives_getHours";
435 435
436 static int _getMinutes(int secondsSinceEpoch, bool isUtc) 436 static int _getMinutes(int secondsSinceEpoch, bool isUtc)
437 native "DateNatives_getMinutes"; 437 native "DateNatives_getMinutes";
438 438
439 static int _getSeconds(int secondsSinceEpoch, bool isUtc) 439 static int _getSeconds(int secondsSinceEpoch, bool isUtc)
440 native "DateNatives_getSeconds"; 440 native "DateNatives_getSeconds";
441 } 441 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698