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

Side by Side Diff: sdk/lib/core/date_time.dart

Issue 1493033003: Add microsecond support to DateTime. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comment. Created 5 years 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
« no previous file with comments | « sdk/lib/_internal/js_runtime/lib/core_patch.dart ('k') | tests/corelib/date_time4_test.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 4
5 part of dart.core; 5 part of dart.core;
6 6
7 /** 7 /**
8 * An instant in time, such as July 20, 1969, 8:18pm GMT. 8 * An instant in time, such as July 20, 1969, 8:18pm GMT.
9 * 9 *
10 * Create a DateTime object by using one of the constructors 10 * Create a DateTime object by using one of the constructors
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 static const int JUNE = 6; 122 static const int JUNE = 6;
123 static const int JULY = 7; 123 static const int JULY = 7;
124 static const int AUGUST = 8; 124 static const int AUGUST = 8;
125 static const int SEPTEMBER = 9; 125 static const int SEPTEMBER = 9;
126 static const int OCTOBER = 10; 126 static const int OCTOBER = 10;
127 static const int NOVEMBER = 11; 127 static const int NOVEMBER = 11;
128 static const int DECEMBER = 12; 128 static const int DECEMBER = 12;
129 static const int MONTHS_PER_YEAR = 12; 129 static const int MONTHS_PER_YEAR = 12;
130 130
131 /** 131 /**
132 * The number of milliseconds since 132 * The value of this DateTime.
133 * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
134 * 133 *
135 * This value is independent of the time zone. 134 * The content of this field is implementation dependent. On JavaScript it is
136 * 135 * equal to [millisecondsSinceEpoch]. On the VM it is equal to
137 * This value is at most 136 * [microsecondsSinceEpoch].
138 * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch.
139 * In other words: [:millisecondsSinceEpoch.abs() <= 8640000000000000:].
140 *
141 */ 137 */
142 final int millisecondsSinceEpoch; 138 final int _value;
143 139
144 /** 140 /**
145 * True if this [DateTime] is set to UTC time. 141 * True if this [DateTime] is set to UTC time.
146 * 142 *
147 * DateTime dDay = new DateTime.utc(1944, 6, 6); 143 * DateTime dDay = new DateTime.utc(1944, 6, 6);
148 * assert(dDay.isUtc); 144 * assert(dDay.isUtc);
149 * 145 *
150 */ 146 */
151 final bool isUtc; 147 final bool isUtc;
152 148
153 /** 149 /**
154 * Constructs a [DateTime] instance specified in the local time zone. 150 * Constructs a [DateTime] instance specified in the local time zone.
155 * 151 *
156 * For example, 152 * For example,
157 * to create a new DateTime object representing April 29, 2014, 6:04am: 153 * to create a new DateTime object representing April 29, 2014, 6:04am:
158 * 154 *
159 * DateTime annularEclipse = new DateTime(2014, DateTime.APRIL, 29, 6, 4); 155 * DateTime annularEclipse = new DateTime(2014, DateTime.APRIL, 29, 6, 4);
160 */ 156 */
161 DateTime(int year, 157 DateTime(int year,
162 [int month = 1, 158 [int month = 1,
163 int day = 1, 159 int day = 1,
164 int hour = 0, 160 int hour = 0,
165 int minute = 0, 161 int minute = 0,
166 int second = 0, 162 int second = 0,
167 int millisecond = 0]) 163 int millisecond = 0,
164 int microsecond = 0])
168 : this._internal( 165 : this._internal(
169 year, month, day, hour, minute, second, millisecond, false); 166 year, month, day, hour, minute, second, millisecond, microsecond,
167 false);
170 168
171 /** 169 /**
172 * Constructs a [DateTime] instance specified in the UTC time zone. 170 * Constructs a [DateTime] instance specified in the UTC time zone.
173 * 171 *
174 * DateTime dDay = new DateTime.utc(1944, DateTime.JUNE, 6); 172 * DateTime dDay = new DateTime.utc(1944, DateTime.JUNE, 6);
175 */ 173 */
176 DateTime.utc(int year, 174 DateTime.utc(int year,
177 [int month = 1, 175 [int month = 1,
178 int day = 1, 176 int day = 1,
179 int hour = 0, 177 int hour = 0,
180 int minute = 0, 178 int minute = 0,
181 int second = 0, 179 int second = 0,
182 int millisecond = 0]) 180 int millisecond = 0,
181 int microsecond = 0])
183 : this._internal( 182 : this._internal(
184 year, month, day, hour, minute, second, millisecond, true); 183 year, month, day, hour, minute, second, millisecond, microsecond,
184 true);
185 185
186 /** 186 /**
187 * Constructs a [DateTime] instance with current date and time in the 187 * Constructs a [DateTime] instance with current date and time in the
188 * local time zone. 188 * local time zone.
189 * 189 *
190 * DateTime thisInstant = new DateTime.now(); 190 * DateTime thisInstant = new DateTime.now();
191 * 191 *
192 */ 192 */
193 DateTime.now() : this._now(); 193 DateTime.now() : this._now();
194 194
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 * yeardate ::= year colon_opt month colon_opt day 249 * yeardate ::= year colon_opt month colon_opt day
250 * year ::= sign_opt digit{4,6} 250 * year ::= sign_opt digit{4,6}
251 * colon_opt :: <empty> | ':' 251 * colon_opt :: <empty> | ':'
252 * sign ::= '+' | '-' 252 * sign ::= '+' | '-'
253 * sign_opt ::= <empty> | sign 253 * sign_opt ::= <empty> | sign
254 * month ::= digit{2} 254 * month ::= digit{2}
255 * day ::= digit{2} 255 * day ::= digit{2}
256 * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt 256 * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt
257 * minutes_opt ::= <empty> | colon_opt digit{2} seconds_opt 257 * minutes_opt ::= <empty> | colon_opt digit{2} seconds_opt
258 * seconds_opt ::= <empty> | colon_opt digit{2} millis_opt 258 * seconds_opt ::= <empty> | colon_opt digit{2} millis_opt
259 * millis_opt ::= <empty> | '.' digit{1,6} 259 * micros_opt ::= <empty> | '.' digit{1,6}
260 * timezone_opt ::= <empty> | space_opt timezone 260 * timezone_opt ::= <empty> | space_opt timezone
261 * space_opt :: ' ' | <empty> 261 * space_opt :: ' ' | <empty>
262 * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt 262 * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt
263 * timezonemins_opt ::= <empty> | colon_opt digit{2} 263 * timezonemins_opt ::= <empty> | colon_opt digit{2}
264 */ 264 */
265 final RegExp re = new RegExp( 265 final RegExp re = new RegExp(
266 r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // Day part. 266 r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // Day part.
267 r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d{1,6}))?)?)?' // Time part. 267 r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d{1,6}))?)?)?' // Time part.
268 r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // Timezone part. 268 r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // Timezone part.
269 269
270 Match match = re.firstMatch(formattedString); 270 Match match = re.firstMatch(formattedString);
271 if (match != null) { 271 if (match != null) {
272 int parseIntOrZero(String matched) { 272 int parseIntOrZero(String matched) {
273 if (matched == null) return 0; 273 if (matched == null) return 0;
274 return int.parse(matched); 274 return int.parse(matched);
275 } 275 }
276 276
277 // Parses fractional second digits of '.(\d{1,6})' into milliseconds. 277 // Parses fractional second digits of '.(\d{1,6})' into the combined
278 // Uses first three digits (assumed to be zero if not there), and 278 // microseconds.
279 // rounds up if fourth digit is 5 or greater. 279 int parseMilliAndMicroseconds(String matched) {
280 // Should be equivalent to `(double.parse(".$matchd")*1000).round()`.
281 int parseMilliseconds(String matched) {
282 if (matched == null) return 0; 280 if (matched == null) return 0;
283 int length = matched.length; 281 int length = matched.length;
284 assert(length >= 1); 282 assert(length >= 1);
285 assert(length <= 6); 283 assert(length <= 6);
286 284
287 int result = (matched.codeUnitAt(0) ^ 0x30); 285 int result = 0;
288 if (length <= 3) { 286 for (int i = 0; i < 6; i++) {
289 int i = 1; 287 result *= 10;
290 while (i < length) { 288 if (i < matched.length) {
291 result *= 10;
292 result += matched.codeUnitAt(i) ^ 0x30; 289 result += matched.codeUnitAt(i) ^ 0x30;
293 i++;
294 } 290 }
295 while (i < 3) {
296 result *= 10;
297 i++;
298 }
299 return result;
300 }
301 // Parse the prefix from 0..3 without creating a new substring.
302 result = result * 10 + (matched.codeUnitAt(1) ^ 0x30);
303 result = result * 10 + (matched.codeUnitAt(2) ^ 0x30);
304 if (matched.codeUnitAt(3) >= 0x35) {
305 result += 1;
306 } 291 }
307 return result; 292 return result;
308 } 293 }
309 294
310 int years = int.parse(match[1]); 295 int years = int.parse(match[1]);
311 int month = int.parse(match[2]); 296 int month = int.parse(match[2]);
312 int day = int.parse(match[3]); 297 int day = int.parse(match[3]);
313 int hour = parseIntOrZero(match[4]); 298 int hour = parseIntOrZero(match[4]);
314 int minute = parseIntOrZero(match[5]); 299 int minute = parseIntOrZero(match[5]);
315 int second = parseIntOrZero(match[6]); 300 int second = parseIntOrZero(match[6]);
316 bool addOneMillisecond = false; 301 bool addOneMillisecond = false;
317 int millisecond = parseMilliseconds(match[7]); 302 int milliAndMicroseconds = parseMilliAndMicroseconds(match[7]);
318 if (millisecond == 1000) { 303 int millisecond =
319 addOneMillisecond = true; 304 milliAndMicroseconds ~/ Duration.MICROSECONDS_PER_MILLISECOND;
320 millisecond = 999; 305 int microsecond =
321 } 306 milliAndMicroseconds.remainder(Duration.MICROSECONDS_PER_MILLISECOND);
322 bool isUtc = false; 307 bool isUtc = false;
323 if (match[8] != null) { // timezone part 308 if (match[8] != null) { // timezone part
324 isUtc = true; 309 isUtc = true;
325 if (match[9] != null) { 310 if (match[9] != null) {
326 // timezone other than 'Z' and 'z'. 311 // timezone other than 'Z' and 'z'.
327 int sign = (match[9] == '-') ? -1 : 1; 312 int sign = (match[9] == '-') ? -1 : 1;
328 int hourDifference = int.parse(match[10]); 313 int hourDifference = int.parse(match[10]);
329 int minuteDifference = parseIntOrZero(match[11]); 314 int minuteDifference = parseIntOrZero(match[11]);
330 minuteDifference += 60 * hourDifference; 315 minuteDifference += 60 * hourDifference;
331 minute -= sign * minuteDifference; 316 minute -= sign * minuteDifference;
332 } 317 }
333 } 318 }
334 int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch( 319 int value = _brokenDownDateToValue(
335 years, month, day, hour, minute, second, millisecond, isUtc); 320 years, month, day, hour, minute, second, millisecond, microsecond,
336 if (millisecondsSinceEpoch == null) { 321 isUtc);
322 if (value == null) {
337 throw new FormatException("Time out of range", formattedString); 323 throw new FormatException("Time out of range", formattedString);
338 } 324 }
339 if (addOneMillisecond) millisecondsSinceEpoch++; 325 return new DateTime._withValue(value, isUtc: isUtc);
340 return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
341 isUtc: isUtc);
342 } else { 326 } else {
343 throw new FormatException("Invalid date format", formattedString); 327 throw new FormatException("Invalid date format", formattedString);
344 } 328 }
345 } 329 }
346 330
347 static const int _MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000; 331 static const int _MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
348 332
349 /** 333 /**
350 * Constructs a new [DateTime] instance 334 * Constructs a new [DateTime] instance
351 * with the given [millisecondsSinceEpoch]. 335 * with the given [millisecondsSinceEpoch].
352 * 336 *
353 * If [isUtc] is false then the date is in the local time zone. 337 * If [isUtc] is false then the date is in the local time zone.
354 * 338 *
355 * The constructed [DateTime] represents 339 * The constructed [DateTime] represents
356 * 1970-01-01T00:00:00Z + [millisecondsSinceEpoch] ms in the given 340 * 1970-01-01T00:00:00Z + [millisecondsSinceEpoch] ms in the given
357 * time zone (local or UTC). 341 * time zone (local or UTC).
358 */ 342 */
359 DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch, 343 external DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
360 {bool isUtc: false}) 344 {bool isUtc: false});
361 : this.millisecondsSinceEpoch = millisecondsSinceEpoch, 345
362 this.isUtc = isUtc { 346 /**
363 if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH) { 347 * Constructs a new [DateTime] instance
348 * with the given [microsecondsSinceEpoch].
349 *
350 * If [isUtc] is false then the date is in the local time zone.
351 *
352 * The constructed [DateTime] represents
353 * 1970-01-01T00:00:00Z + [microsecondsSinceEpoch] us in the given
354 * time zone (local or UTC).
355 */
356 external DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
357 {bool isUtc: false});
358
359 /**
360 * Constructs a new [DateTime] instance with the given value.
361 *
362 * If [isUtc] is false then the date is in the local time zone.
363 */
364 DateTime._withValue(this._value, {this.isUtc}) {
365 if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH ||
366 (millisecondsSinceEpoch.abs() == _MAX_MILLISECONDS_SINCE_EPOCH &&
367 microsecond != 0)) {
364 throw new ArgumentError(millisecondsSinceEpoch); 368 throw new ArgumentError(millisecondsSinceEpoch);
365 } 369 }
366 if (isUtc == null) throw new ArgumentError(isUtc); 370 if (isUtc == null) throw new ArgumentError(isUtc);
367 } 371 }
368 372
369 /** 373 /**
370 * Returns true if [other] is a [DateTime] at the same moment and in the 374 * Returns true if [other] is a [DateTime] at the same moment and in the
371 * same time zone (UTC or local). 375 * same time zone (UTC or local).
372 * 376 *
373 * DateTime dDayUtc = new DateTime.utc(1944, DateTime.JUNE, 6); 377 * DateTime dDayUtc = new DateTime.utc(1944, DateTime.JUNE, 6);
374 * DateTime dDayLocal = new DateTime(1944, DateTime.JUNE, 6); 378 * DateTime dDayLocal = new DateTime(1944, DateTime.JUNE, 6);
375 * 379 *
376 * assert(dDayUtc.isAtSameMomentAs(dDayLocal) == false); 380 * assert(dDayUtc.isAtSameMomentAs(dDayLocal) == false);
377 * 381 *
378 * See [isAtSameMomentAs] for a comparison that adjusts for time zone. 382 * See [isAtSameMomentAs] for a comparison that adjusts for time zone.
379 */ 383 */
380 bool operator ==(other) { 384 bool operator ==(other) {
381 if (!(other is DateTime)) return false; 385 if (!(other is DateTime)) return false;
382 return (millisecondsSinceEpoch == other.millisecondsSinceEpoch && 386 return (_value == other._value && isUtc == other.isUtc);
383 isUtc == other.isUtc);
384 } 387 }
385 388
386 /** 389 /**
387 * Returns true if [this] occurs before [other]. 390 * Returns true if [this] occurs before [other].
388 * 391 *
389 * The comparison is independent 392 * The comparison is independent
390 * of whether the time is in UTC or in the local time zone. 393 * of whether the time is in UTC or in the local time zone.
391 * 394 *
392 * DateTime berlinWallFell = new DateTime(1989, 11, 9); 395 * DateTime berlinWallFell = new DateTime(1989, 11, 9);
393 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); 396 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
394 * 397 *
395 * assert(berlinWallFell.isBefore(moonLanding) == false); 398 * assert(berlinWallFell.isBefore(moonLanding) == false);
396 * 399 *
397 */ 400 */
398 bool isBefore(DateTime other) { 401 bool isBefore(DateTime other) {
399 return millisecondsSinceEpoch < other.millisecondsSinceEpoch; 402 return _value < other._value;
400 } 403 }
401 404
402 /** 405 /**
403 * Returns true if [this] occurs after [other]. 406 * Returns true if [this] occurs after [other].
404 * 407 *
405 * The comparison is independent 408 * The comparison is independent
406 * of whether the time is in UTC or in the local time zone. 409 * of whether the time is in UTC or in the local time zone.
407 * 410 *
408 * DateTime berlinWallFell = new DateTime(1989, 11, 9); 411 * DateTime berlinWallFell = new DateTime(1989, 11, 9);
409 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); 412 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
410 * 413 *
411 * assert(berlinWallFell.isAfter(moonLanding) == true); 414 * assert(berlinWallFell.isAfter(moonLanding) == true);
412 * 415 *
413 */ 416 */
414 bool isAfter(DateTime other) { 417 bool isAfter(DateTime other) {
415 return millisecondsSinceEpoch > other.millisecondsSinceEpoch; 418 return _value > other._value;
416 } 419 }
417 420
418 /** 421 /**
419 * Returns true if [this] occurs at the same moment as [other]. 422 * Returns true if [this] occurs at the same moment as [other].
420 * 423 *
421 * The comparison is independent of whether the time is in UTC or in the local 424 * The comparison is independent of whether the time is in UTC or in the local
422 * time zone. 425 * time zone.
423 * 426 *
424 * DateTime berlinWallFell = new DateTime(1989, 11, 9); 427 * DateTime berlinWallFell = new DateTime(1989, 11, 9);
425 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); 428 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
426 * 429 *
427 * assert(berlinWallFell.isAtSameMomentAs(moonLanding) == false); 430 * assert(berlinWallFell.isAtSameMomentAs(moonLanding) == false);
428 */ 431 */
429 bool isAtSameMomentAs(DateTime other) { 432 bool isAtSameMomentAs(DateTime other) {
430 return millisecondsSinceEpoch == other.millisecondsSinceEpoch; 433 return _value == other._value;
431 } 434 }
432 435
433 /** 436 /**
434 * Compares this DateTime object to [other], 437 * Compares this DateTime object to [other],
435 * returning zero if the values are equal. 438 * returning zero if the values are equal.
436 * 439 *
437 * This function returns a negative integer 440 * This function returns a negative integer
438 * if this DateTime is smaller (earlier) than [other], 441 * if this DateTime is smaller (earlier) than [other],
439 * or a positive integer if it is greater (later). 442 * or a positive integer if it is greater (later).
440 */ 443 */
441 int compareTo(DateTime other) 444 int compareTo(DateTime other) => _value.compareTo(other._value);
442 => millisecondsSinceEpoch.compareTo(other.millisecondsSinceEpoch);
443 445
444 int get hashCode => millisecondsSinceEpoch; 446 int get hashCode => (_value ^ (_value >> 30)) & 0x3FFFFFFF;
445 447
446 /** 448 /**
447 * Returns this DateTime value in the local time zone. 449 * Returns this DateTime value in the local time zone.
448 * 450 *
449 * Returns [this] if it is already in the local time zone. 451 * Returns [this] if it is already in the local time zone.
450 * Otherwise this method is equivalent to: 452 * Otherwise this method is equivalent to:
451 * 453 *
452 * new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch, 454 * new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
453 * isUtc: false) 455 * isUtc: false)
454 */ 456 */
455 DateTime toLocal() { 457 DateTime toLocal() {
456 if (isUtc) { 458 if (isUtc) {
457 return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch, 459 return new DateTime._withValue(_value, isUtc: false);
458 isUtc: false);
459 } 460 }
460 return this; 461 return this;
461 } 462 }
462 463
463 /** 464 /**
464 * Returns this DateTime value in the UTC time zone. 465 * Returns this DateTime value in the UTC time zone.
465 * 466 *
466 * Returns [this] if it is already in UTC. 467 * Returns [this] if it is already in UTC.
467 * Otherwise this method is equivalent to: 468 * Otherwise this method is equivalent to:
468 * 469 *
469 * new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch, 470 * new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
470 * isUtc: true) 471 * isUtc: true)
471 */ 472 */
472 DateTime toUtc() { 473 DateTime toUtc() {
473 if (isUtc) return this; 474 if (isUtc) return this;
474 return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch, 475 return new DateTime._withValue(_value, isUtc: true);
475 isUtc: true);
476 } 476 }
477 477
478 static String _fourDigits(int n) { 478 static String _fourDigits(int n) {
479 int absN = n.abs(); 479 int absN = n.abs();
480 String sign = n < 0 ? "-" : ""; 480 String sign = n < 0 ? "-" : "";
481 if (absN >= 1000) return "$n"; 481 if (absN >= 1000) return "$n";
482 if (absN >= 100) return "${sign}0$absN"; 482 if (absN >= 100) return "${sign}0$absN";
483 if (absN >= 10) return "${sign}00$absN"; 483 if (absN >= 10) return "${sign}00$absN";
484 return "${sign}000$absN"; 484 return "${sign}000$absN";
485 } 485 }
(...skipping 29 matching lines...) Expand all
515 * The resulting string can be parsed back using [parse]. 515 * The resulting string can be parsed back using [parse].
516 */ 516 */
517 String toString() { 517 String toString() {
518 String y = _fourDigits(year); 518 String y = _fourDigits(year);
519 String m = _twoDigits(month); 519 String m = _twoDigits(month);
520 String d = _twoDigits(day); 520 String d = _twoDigits(day);
521 String h = _twoDigits(hour); 521 String h = _twoDigits(hour);
522 String min = _twoDigits(minute); 522 String min = _twoDigits(minute);
523 String sec = _twoDigits(second); 523 String sec = _twoDigits(second);
524 String ms = _threeDigits(millisecond); 524 String ms = _threeDigits(millisecond);
525 String us = microsecond == 0 ? "" : _threeDigits(microsecond);
525 if (isUtc) { 526 if (isUtc) {
526 return "$y-$m-$d $h:$min:$sec.${ms}Z"; 527 return "$y-$m-$d $h:$min:$sec.$ms${us}Z";
527 } else { 528 } else {
528 return "$y-$m-$d $h:$min:$sec.$ms"; 529 return "$y-$m-$d $h:$min:$sec.$ms$us";
529 } 530 }
530 } 531 }
531 532
532 /** 533 /**
533 * Returns an ISO-8601 full-precision extended format representation. 534 * Returns an ISO-8601 full-precision extended format representation.
534 * 535 *
535 * The format is `yyyy-MM-ddTHH:mm:ss.sssZ` for UTC time, and 536 * The format is `yyyy-MM-ddTHH:mm:ss.mmmuuuZ` for UTC time, and
536 * `yyyy-MM-ddTHH:mm:ss.sss` (no trailing "Z") for local/non-UTC time, 537 * `yyyy-MM-ddTHH:mm:ss.mmmuuu` (no trailing "Z") for local/non-UTC time,
537 * where: 538 * where:
538 * 539 *
539 * * `yyyy` is a, possibly negative, four digit representation of the year, 540 * * `yyyy` is a, possibly negative, four digit representation of the year,
540 * if the year is in the range -9999 to 9999, 541 * if the year is in the range -9999 to 9999,
541 * otherwise it is a signed six digit representation of the year. 542 * otherwise it is a signed six digit representation of the year.
542 * * `MM` is the month in the range 01 to 12, 543 * * `MM` is the month in the range 01 to 12,
543 * * `dd` is the day of the month in the range 01 to 31, 544 * * `dd` is the day of the month in the range 01 to 31,
544 * * `HH` are hours in the range 00 to 23, 545 * * `HH` are hours in the range 00 to 23,
545 * * `mm` are minutes in the range 00 to 59, 546 * * `mm` are minutes in the range 00 to 59,
546 * * `ss` are seconds in the range 00 to 59 (no leap seconds), and 547 * * `ss` are seconds in the range 00 to 59 (no leap seconds),
547 * * `sss` are milliseconds in the range 000 to 999. 548 * * `mmm` are microseconds in the range 000 to 999, and
549 * * `uuu` are microseconds in the range 001 to 999. If [microsecond] equals
550 * 0, then this part is omitted.
548 * 551 *
549 * The resulting string can be parsed back using [parse]. 552 * The resulting string can be parsed back using [parse].
550 */ 553 */
551 String toIso8601String() { 554 String toIso8601String() {
552 String y = (year >= -9999 && year <= 9999) ? _fourDigits(year) 555 String y = (year >= -9999 && year <= 9999) ? _fourDigits(year)
553 : _sixDigits(year); 556 : _sixDigits(year);
554 String m = _twoDigits(month); 557 String m = _twoDigits(month);
555 String d = _twoDigits(day); 558 String d = _twoDigits(day);
556 String h = _twoDigits(hour); 559 String h = _twoDigits(hour);
557 String min = _twoDigits(minute); 560 String min = _twoDigits(minute);
558 String sec = _twoDigits(second); 561 String sec = _twoDigits(second);
559 String ms = _threeDigits(millisecond); 562 String ms = _threeDigits(millisecond);
563 String us = microsecond == 0 ? "" : _threeDigits(microsecond);
560 if (isUtc) { 564 if (isUtc) {
561 return "$y-$m-${d}T$h:$min:$sec.${ms}Z"; 565 return "$y-$m-${d}T$h:$min:$sec.$ms${us}Z";
562 } else { 566 } else {
563 return "$y-$m-${d}T$h:$min:$sec.$ms"; 567 return "$y-$m-${d}T$h:$min:$sec.$ms$us";
564 } 568 }
565 } 569 }
566 570
567 /** 571 /**
568 * Returns a new [DateTime] instance with [duration] added to [this]. 572 * Returns a new [DateTime] instance with [duration] added to [this].
569 * 573 *
570 * DateTime today = new DateTime.now(); 574 * DateTime today = new DateTime.now();
571 * DateTime sixtyDaysFromNow = today.add(new Duration(days: 60)); 575 * DateTime sixtyDaysFromNow = today.add(new Duration(days: 60));
572 */ 576 */
573 DateTime add(Duration duration) { 577 external DateTime add(Duration duration);
574 int ms = millisecondsSinceEpoch;
575 return new DateTime.fromMillisecondsSinceEpoch(
576 ms + duration.inMilliseconds, isUtc: isUtc);
577 }
578 578
579 /** 579 /**
580 * Returns a new [DateTime] instance with [duration] subtracted from [this]. 580 * Returns a new [DateTime] instance with [duration] subtracted from [this].
581 * 581 *
582 * DateTime today = new DateTime.now(); 582 * DateTime today = new DateTime.now();
583 * DateTime sixtyDaysAgo = today.subtract(new Duration(days: 60)); 583 * DateTime sixtyDaysAgo = today.subtract(new Duration(days: 60));
584 */ 584 */
585 DateTime subtract(Duration duration) { 585 external DateTime subtract(Duration duration);
586 int ms = millisecondsSinceEpoch;
587 return new DateTime.fromMillisecondsSinceEpoch(
588 ms - duration.inMilliseconds, isUtc: isUtc);
589 }
590 586
591 /** 587 /**
592 * Returns a [Duration] with the difference between [this] and [other]. 588 * Returns a [Duration] with the difference between [this] and [other].
593 * 589 *
594 * DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9); 590 * DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9);
595 * DateTime dDay = new DateTime(1944, DateTime.JUNE, 6); 591 * DateTime dDay = new DateTime(1944, DateTime.JUNE, 6);
596 * 592 *
597 * Duration difference = berlinWallFell.difference(dDay); 593 * Duration difference = berlinWallFell.difference(dDay);
598 * assert(difference.inDays == 16592); 594 * assert(difference.inDays == 16592);
599 */ 595 */
600 596 external Duration difference(DateTime other);
601 Duration difference(DateTime other) {
602 int ms = millisecondsSinceEpoch;
603 int otherMs = other.millisecondsSinceEpoch;
604 return new Duration(milliseconds: ms - otherMs);
605 }
606 597
607 external DateTime._internal(int year, 598 external DateTime._internal(int year,
608 int month, 599 int month,
609 int day, 600 int day,
610 int hour, 601 int hour,
611 int minute, 602 int minute,
612 int second, 603 int second,
613 int millisecond, 604 int millisecond,
605 int microsecond,
614 bool isUtc); 606 bool isUtc);
607
615 external DateTime._now(); 608 external DateTime._now();
616 /// Returns the time as milliseconds since epoch, or null if the 609
617 /// values are out of range. 610 /// Returns the time as value (millisecond or microsecond since epoch), or
618 external static int _brokenDownDateToMillisecondsSinceEpoch( 611 /// null if the values are out of range.
612 external static int _brokenDownDateToValue(
619 int year, int month, int day, int hour, int minute, int second, 613 int year, int month, int day, int hour, int minute, int second,
620 int millisecond, bool isUtc); 614 int millisecond, int microsecond, bool isUtc);
615
616 /**
617 * The number of milliseconds since
618 * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
619 *
620 * This value is independent of the time zone.
621 *
622 * This value is at most
623 * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch.
624 * In other words: `millisecondsSinceEpoch.abs() <= 8640000000000000`.
625 */
626 external int get millisecondsSinceEpoch;
627
628 /**
629 * The number of microseconds since
630 * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
631 *
632 * This value is independent of the time zone.
633 *
634 * This value is at most
635 * 8,640,000,000,000,000,000us (100,000,000 days) from the Unix epoch.
636 * In other words: `microsecondsSinceEpoch.abs() <= 8640000000000000000`.
637 *
638 * Note that this value does not fit into 53 bits (the size of a IEEE double).
639 * A JavaScript number is not able to hold this value.
640 */
641 external int get microsecondsSinceEpoch;
621 642
622 /** 643 /**
623 * The abbreviated time zone name&mdash;for example, 644 * The abbreviated time zone name&mdash;for example,
624 * [:"CET":] or [:"CEST":]. 645 * [:"CET":] or [:"CEST":].
625 */ 646 */
626 external String get timeZoneName; 647 external String get timeZoneName;
627 648
628 /** 649 /**
629 * The time zone offset, which 650 * The time zone offset, which
630 * is the difference between local time and UTC. 651 * is the difference between local time and UTC.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 709
689 /** 710 /**
690 * The millisecond [0...999]. 711 * The millisecond [0...999].
691 * 712 *
692 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); 713 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
693 * assert(moonLanding.millisecond == 0); 714 * assert(moonLanding.millisecond == 0);
694 */ 715 */
695 external int get millisecond; 716 external int get millisecond;
696 717
697 /** 718 /**
719 * The microsecond [0...999].
720 *
721 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
722 * assert(moonLanding.microsecond == 0);
723 */
724 external int get microsecond;
725
726 /**
698 * The day of the week [MONDAY]..[SUNDAY]. 727 * The day of the week [MONDAY]..[SUNDAY].
699 * 728 *
700 * In accordance with ISO 8601 729 * In accordance with ISO 8601
701 * a week starts with Monday, which has the value 1. 730 * a week starts with Monday, which has the value 1.
702 * 731 *
703 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); 732 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
704 * assert(moonLanding.weekday == 7); 733 * assert(moonLanding.weekday == 7);
705 * assert(moonLanding.weekday == DateTime.SUNDAY); 734 * assert(moonLanding.weekday == DateTime.SUNDAY);
706 * 735 *
707 */ 736 */
708 external int get weekday; 737 external int get weekday;
709 } 738 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/js_runtime/lib/core_patch.dart ('k') | tests/corelib/date_time4_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698