| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 part of dart.core; | |
| 6 | |
| 7 /** | |
| 8 * An instant in time, such as July 20, 1969, 8:18pm GMT. | |
| 9 * | |
| 10 * Create a DateTime object by using one of the constructors | |
| 11 * or by parsing a correctly formatted string, | |
| 12 * which complies with a subset of ISO 8601. | |
| 13 * Note that hours are specified between 0 and 23, | |
| 14 * as in a 24-hour clock. | |
| 15 * For example: | |
| 16 * | |
| 17 * DateTime now = new DateTime.now(); | |
| 18 * DateTime berlinWallFell = new DateTime(1989, 11, 9); | |
| 19 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); // 8:18pm | |
| 20 * | |
| 21 * A DateTime object is anchored either in the UTC time zone | |
| 22 * or in the local time zone of the current computer | |
| 23 * when the object is created. | |
| 24 * | |
| 25 * Once created, neither the value nor the time zone | |
| 26 * of a DateTime object may be changed. | |
| 27 * | |
| 28 * You can use properties to get | |
| 29 * the individual units of a DateTime object. | |
| 30 * | |
| 31 * assert(berlinWallFell.month == 11); | |
| 32 * assert(moonLanding.hour == 20); | |
| 33 * | |
| 34 * For convenience and readability, | |
| 35 * the DateTime class provides a constant for each day and month | |
| 36 * name—for example, [AUGUST] and [FRIDAY]. | |
| 37 * You can use these constants to improve code readibility: | |
| 38 * | |
| 39 * DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9); | |
| 40 * assert(berlinWallFell.weekday == DateTime.THURSDAY); | |
| 41 * | |
| 42 * Day and month values begin at 1, and the week starts on Monday. | |
| 43 * That is, the constants [JANUARY] and [MONDAY] are both 1. | |
| 44 * | |
| 45 * ## Working with UTC and local time | |
| 46 * | |
| 47 * A DateTime object is in the local time zone | |
| 48 * unless explicitly created in the UTC time zone. | |
| 49 * | |
| 50 * DateTime dDay = new DateTime.utc(1944, 6, 6); | |
| 51 * | |
| 52 * Use [isUtc] to determine whether a DateTime object is based in UTC. | |
| 53 * Use the methods [toLocal] and [toUtc] | |
| 54 * to get the equivalent date/time value specified in the other time zone. | |
| 55 * Use [timeZoneName] to get an abbreviated name of the time zone | |
| 56 * for the DateTime object. | |
| 57 * To find the difference | |
| 58 * between UTC and the time zone of a DateTime object | |
| 59 * call [timeZoneOffset]. | |
| 60 * | |
| 61 * ## Comparing DateTime objects | |
| 62 * | |
| 63 * The DateTime class contains several handy methods, | |
| 64 * such as [isAfter], [isBefore], and [isAtSameMomentAs], | |
| 65 * for comparing DateTime objects. | |
| 66 * | |
| 67 * assert(berlinWallFell.isAfter(moonLanding) == true); | |
| 68 * assert(berlinWallFell.isBefore(moonLanding) == false); | |
| 69 * | |
| 70 * ## Using DateTime with Duration | |
| 71 * | |
| 72 * Use the [add] and [subtract] methods with a [Duration] object | |
| 73 * to create a new DateTime object based on another. | |
| 74 * For example, to find the date that is sixty days after today, write: | |
| 75 * | |
| 76 * DateTime today = new DateTime.now(); | |
| 77 * DateTime sixtyDaysFromNow = today.add(new Duration(days: 60)); | |
| 78 * | |
| 79 * To find out how much time is between two DateTime objects use | |
| 80 * [difference], which returns a [Duration] object: | |
| 81 * | |
| 82 * Duration difference = berlinWallFell.difference(moonLanding) | |
| 83 * assert(difference.inDays == 7416); | |
| 84 * | |
| 85 * The difference between two dates in different time zones | |
| 86 * is just the number of nanoseconds between the two points in time. | |
| 87 * It doesn't take calendar days into account. | |
| 88 * That means that the difference between two midnights in local time may be | |
| 89 * less than 24 hours times the number of days between them, | |
| 90 * if there is a daylight saving change in between. | |
| 91 * If the difference above is calculated using Australian local time, the | |
| 92 * difference is 7415 days and 23 hours, which is only 7415 whole days as | |
| 93 * reported by `inDays`. | |
| 94 * | |
| 95 * ## Other resources | |
| 96 * | |
| 97 * See [Duration] to represent a span of time. | |
| 98 * See [Stopwatch] to measure timespans. | |
| 99 * | |
| 100 * The DateTime class does not provide internationalization. | |
| 101 * To internationalize your code, use | |
| 102 * the [intl](http://pub.dartlang.org/packages/intl) package. | |
| 103 * | |
| 104 */ | |
| 105 class DateTime implements Comparable<DateTime> { | |
| 106 // Weekday constants that are returned by [weekday] method: | |
| 107 static const int MONDAY = 1; | |
| 108 static const int TUESDAY = 2; | |
| 109 static const int WEDNESDAY = 3; | |
| 110 static const int THURSDAY = 4; | |
| 111 static const int FRIDAY = 5; | |
| 112 static const int SATURDAY = 6; | |
| 113 static const int SUNDAY = 7; | |
| 114 static const int DAYS_PER_WEEK = 7; | |
| 115 | |
| 116 // Month constants that are returned by the [month] getter. | |
| 117 static const int JANUARY = 1; | |
| 118 static const int FEBRUARY = 2; | |
| 119 static const int MARCH = 3; | |
| 120 static const int APRIL = 4; | |
| 121 static const int MAY = 5; | |
| 122 static const int JUNE = 6; | |
| 123 static const int JULY = 7; | |
| 124 static const int AUGUST = 8; | |
| 125 static const int SEPTEMBER = 9; | |
| 126 static const int OCTOBER = 10; | |
| 127 static const int NOVEMBER = 11; | |
| 128 static const int DECEMBER = 12; | |
| 129 static const int MONTHS_PER_YEAR = 12; | |
| 130 | |
| 131 /** | |
| 132 * The value of this DateTime. | |
| 133 * | |
| 134 * The content of this field is implementation dependent. On JavaScript it is | |
| 135 * equal to [millisecondsSinceEpoch]. On the VM it is equal to | |
| 136 * [microsecondsSinceEpoch]. | |
| 137 */ | |
| 138 final int _value; | |
| 139 | |
| 140 /** | |
| 141 * True if this [DateTime] is set to UTC time. | |
| 142 * | |
| 143 * DateTime dDay = new DateTime.utc(1944, 6, 6); | |
| 144 * assert(dDay.isUtc); | |
| 145 * | |
| 146 */ | |
| 147 final bool isUtc; | |
| 148 | |
| 149 /** | |
| 150 * Constructs a [DateTime] instance specified in the local time zone. | |
| 151 * | |
| 152 * For example, | |
| 153 * to create a new DateTime object representing April 29, 2014, 6:04am: | |
| 154 * | |
| 155 * DateTime annularEclipse = new DateTime(2014, DateTime.APRIL, 29, 6, 4); | |
| 156 */ | |
| 157 DateTime(int year, | |
| 158 [int month = 1, | |
| 159 int day = 1, | |
| 160 int hour = 0, | |
| 161 int minute = 0, | |
| 162 int second = 0, | |
| 163 int millisecond = 0, | |
| 164 int microsecond = 0]) | |
| 165 : this._internal( | |
| 166 year, month, day, hour, minute, second, millisecond, microsecond, | |
| 167 false); | |
| 168 | |
| 169 /** | |
| 170 * Constructs a [DateTime] instance specified in the UTC time zone. | |
| 171 * | |
| 172 * DateTime dDay = new DateTime.utc(1944, DateTime.JUNE, 6); | |
| 173 */ | |
| 174 DateTime.utc(int year, | |
| 175 [int month = 1, | |
| 176 int day = 1, | |
| 177 int hour = 0, | |
| 178 int minute = 0, | |
| 179 int second = 0, | |
| 180 int millisecond = 0, | |
| 181 int microsecond = 0]) | |
| 182 : this._internal( | |
| 183 year, month, day, hour, minute, second, millisecond, microsecond, | |
| 184 true); | |
| 185 | |
| 186 /** | |
| 187 * Constructs a [DateTime] instance with current date and time in the | |
| 188 * local time zone. | |
| 189 * | |
| 190 * DateTime thisInstant = new DateTime.now(); | |
| 191 * | |
| 192 */ | |
| 193 DateTime.now() : this._now(); | |
| 194 | |
| 195 /** | |
| 196 * Constructs a new [DateTime] instance based on [formattedString]. | |
| 197 * | |
| 198 * Throws a [FormatException] if the input cannot be parsed. | |
| 199 * | |
| 200 * The function parses a subset of ISO 8601 | |
| 201 * which includes the subset accepted by RFC 3339. | |
| 202 * | |
| 203 * The accepted inputs are currently: | |
| 204 * | |
| 205 * * A date: A signed four-to-six digit year, two digit month and | |
| 206 * two digit day, optionally separated by `-` characters. | |
| 207 * Examples: "19700101", "-0004-12-24", "81030-04-01". | |
| 208 * * An optional time part, separated from the date by either `T` or a space. | |
| 209 * The time part is a two digit hour, | |
| 210 * then optionally a two digit minutes value, | |
| 211 * then optionally a two digit seconds value, and | |
| 212 * then optionally a '.' followed by a one-to-six digit second fraction. | |
| 213 * The minuts and seconds may be separated from the previous parts by a ':'. | |
| 214 * Examples: "12", "12:30:24.124", "123010.50". | |
| 215 * * An optional time-zone offset part, | |
| 216 * possibly separated from the previous by a space. | |
| 217 * The time zone is either 'z' or 'Z', or it is a signed two digit hour | |
| 218 * part and an optional two digit minute part. The sign must be either | |
| 219 * "+" or "-", and can not be omitted. | |
| 220 * The minutes may be separted from the hours by a ':'. | |
| 221 * Examples: "Z", "-10", "01:30", "1130". | |
| 222 * | |
| 223 * This includes the output of both [toString] and [toIso8601String], which | |
| 224 * will be parsed back into a `DateTime` object with the same time as the | |
| 225 * original. | |
| 226 * | |
| 227 * The result is always in either local time or UTC. | |
| 228 * If a time zone offset other than UTC is specified, | |
| 229 * the time is converted to the equivalent UTC time. | |
| 230 * | |
| 231 * Examples of accepted strings: | |
| 232 * | |
| 233 * * `"2012-02-27 13:27:00"` | |
| 234 * * `"2012-02-27 13:27:00.123456z"` | |
| 235 * * `"20120227 13:27:00"` | |
| 236 * * `"20120227T132700"` | |
| 237 * * `"20120227"` | |
| 238 * * `"+20120227"` | |
| 239 * * `"2012-02-27T14Z"` | |
| 240 * * `"2012-02-27T14+00:00"` | |
| 241 * * `"-123450101 00:00:00 Z"`: in the year -12345. | |
| 242 * * `"2002-02-27T14:00:00-0500"`: Same as `"2002-02-27T19:00:00Z"` | |
| 243 */ | |
| 244 // TODO(lrn): restrict incorrect values like 2003-02-29T50:70:80. | |
| 245 // Or not, that may be a breaking change. | |
| 246 static DateTime parse(String formattedString) { | |
| 247 /* | |
| 248 * date ::= yeardate time_opt timezone_opt | |
| 249 * yeardate ::= year colon_opt month colon_opt day | |
| 250 * year ::= sign_opt digit{4,6} | |
| 251 * colon_opt :: <empty> | ':' | |
| 252 * sign ::= '+' | '-' | |
| 253 * sign_opt ::= <empty> | sign | |
| 254 * month ::= digit{2} | |
| 255 * day ::= digit{2} | |
| 256 * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt | |
| 257 * minutes_opt ::= <empty> | colon_opt digit{2} seconds_opt | |
| 258 * seconds_opt ::= <empty> | colon_opt digit{2} millis_opt | |
| 259 * micros_opt ::= <empty> | '.' digit{1,6} | |
| 260 * timezone_opt ::= <empty> | space_opt timezone | |
| 261 * space_opt :: ' ' | <empty> | |
| 262 * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt | |
| 263 * timezonemins_opt ::= <empty> | colon_opt digit{2} | |
| 264 */ | |
| 265 final RegExp re = new RegExp( | |
| 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. | |
| 268 r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // Timezone part. | |
| 269 | |
| 270 Match match = re.firstMatch(formattedString); | |
| 271 if (match != null) { | |
| 272 int parseIntOrZero(String matched) { | |
| 273 if (matched == null) return 0; | |
| 274 return int.parse(matched); | |
| 275 } | |
| 276 | |
| 277 // Parses fractional second digits of '.(\d{1,6})' into the combined | |
| 278 // microseconds. | |
| 279 int parseMilliAndMicroseconds(String matched) { | |
| 280 if (matched == null) return 0; | |
| 281 int length = matched.length; | |
| 282 assert(length >= 1); | |
| 283 assert(length <= 6); | |
| 284 | |
| 285 int result = 0; | |
| 286 for (int i = 0; i < 6; i++) { | |
| 287 result *= 10; | |
| 288 if (i < matched.length) { | |
| 289 result += matched.codeUnitAt(i) ^ 0x30; | |
| 290 } | |
| 291 } | |
| 292 return result; | |
| 293 } | |
| 294 | |
| 295 int years = int.parse(match[1]); | |
| 296 int month = int.parse(match[2]); | |
| 297 int day = int.parse(match[3]); | |
| 298 int hour = parseIntOrZero(match[4]); | |
| 299 int minute = parseIntOrZero(match[5]); | |
| 300 int second = parseIntOrZero(match[6]); | |
| 301 bool addOneMillisecond = false; | |
| 302 int milliAndMicroseconds = parseMilliAndMicroseconds(match[7]); | |
| 303 int millisecond = | |
| 304 milliAndMicroseconds ~/ Duration.MICROSECONDS_PER_MILLISECOND; | |
| 305 int microsecond = | |
| 306 milliAndMicroseconds.remainder(Duration.MICROSECONDS_PER_MILLISECOND); | |
| 307 bool isUtc = false; | |
| 308 if (match[8] != null) { // timezone part | |
| 309 isUtc = true; | |
| 310 if (match[9] != null) { | |
| 311 // timezone other than 'Z' and 'z'. | |
| 312 int sign = (match[9] == '-') ? -1 : 1; | |
| 313 int hourDifference = int.parse(match[10]); | |
| 314 int minuteDifference = parseIntOrZero(match[11]); | |
| 315 minuteDifference += 60 * hourDifference; | |
| 316 minute -= sign * minuteDifference; | |
| 317 } | |
| 318 } | |
| 319 int value = _brokenDownDateToValue( | |
| 320 years, month, day, hour, minute, second, millisecond, microsecond, | |
| 321 isUtc); | |
| 322 if (value == null) { | |
| 323 throw new FormatException("Time out of range", formattedString); | |
| 324 } | |
| 325 return new DateTime._withValue(value, isUtc: isUtc); | |
| 326 } else { | |
| 327 throw new FormatException("Invalid date format", formattedString); | |
| 328 } | |
| 329 } | |
| 330 | |
| 331 static const int _MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000; | |
| 332 | |
| 333 /** | |
| 334 * Constructs a new [DateTime] instance | |
| 335 * with the given [millisecondsSinceEpoch]. | |
| 336 * | |
| 337 * If [isUtc] is false then the date is in the local time zone. | |
| 338 * | |
| 339 * The constructed [DateTime] represents | |
| 340 * 1970-01-01T00:00:00Z + [millisecondsSinceEpoch] ms in the given | |
| 341 * time zone (local or UTC). | |
| 342 */ | |
| 343 external DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch, | |
| 344 {bool isUtc: false}); | |
| 345 | |
| 346 /** | |
| 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)) { | |
| 368 throw new ArgumentError(millisecondsSinceEpoch); | |
| 369 } | |
| 370 if (isUtc == null) throw new ArgumentError(isUtc); | |
| 371 } | |
| 372 | |
| 373 /** | |
| 374 * Returns true if [other] is a [DateTime] at the same moment and in the | |
| 375 * same time zone (UTC or local). | |
| 376 * | |
| 377 * DateTime dDayUtc = new DateTime.utc(1944, DateTime.JUNE, 6); | |
| 378 * DateTime dDayLocal = new DateTime(1944, DateTime.JUNE, 6); | |
| 379 * | |
| 380 * assert(dDayUtc.isAtSameMomentAs(dDayLocal) == false); | |
| 381 * | |
| 382 * See [isAtSameMomentAs] for a comparison that adjusts for time zone. | |
| 383 */ | |
| 384 bool operator ==(other) { | |
| 385 if (!(other is DateTime)) return false; | |
| 386 return (_value == other._value && isUtc == other.isUtc); | |
| 387 } | |
| 388 | |
| 389 /** | |
| 390 * Returns true if [this] occurs before [other]. | |
| 391 * | |
| 392 * The comparison is independent | |
| 393 * of whether the time is in UTC or in the local time zone. | |
| 394 * | |
| 395 * DateTime berlinWallFell = new DateTime(1989, 11, 9); | |
| 396 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 397 * | |
| 398 * assert(berlinWallFell.isBefore(moonLanding) == false); | |
| 399 * | |
| 400 */ | |
| 401 bool isBefore(DateTime other) { | |
| 402 return _value < other._value; | |
| 403 } | |
| 404 | |
| 405 /** | |
| 406 * Returns true if [this] occurs after [other]. | |
| 407 * | |
| 408 * The comparison is independent | |
| 409 * of whether the time is in UTC or in the local time zone. | |
| 410 * | |
| 411 * DateTime berlinWallFell = new DateTime(1989, 11, 9); | |
| 412 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 413 * | |
| 414 * assert(berlinWallFell.isAfter(moonLanding) == true); | |
| 415 * | |
| 416 */ | |
| 417 bool isAfter(DateTime other) { | |
| 418 return _value > other._value; | |
| 419 } | |
| 420 | |
| 421 /** | |
| 422 * Returns true if [this] occurs at the same moment as [other]. | |
| 423 * | |
| 424 * The comparison is independent of whether the time is in UTC or in the local | |
| 425 * time zone. | |
| 426 * | |
| 427 * DateTime berlinWallFell = new DateTime(1989, 11, 9); | |
| 428 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 429 * | |
| 430 * assert(berlinWallFell.isAtSameMomentAs(moonLanding) == false); | |
| 431 */ | |
| 432 bool isAtSameMomentAs(DateTime other) { | |
| 433 return _value == other._value; | |
| 434 } | |
| 435 | |
| 436 /** | |
| 437 * Compares this DateTime object to [other], | |
| 438 * returning zero if the values are equal. | |
| 439 * | |
| 440 * This function returns a negative integer | |
| 441 * if this DateTime is smaller (earlier) than [other], | |
| 442 * or a positive integer if it is greater (later). | |
| 443 */ | |
| 444 int compareTo(DateTime other) => _value.compareTo(other._value); | |
| 445 | |
| 446 int get hashCode => (_value ^ (_value >> 30)) & 0x3FFFFFFF; | |
| 447 | |
| 448 /** | |
| 449 * Returns this DateTime value in the local time zone. | |
| 450 * | |
| 451 * Returns [this] if it is already in the local time zone. | |
| 452 * Otherwise this method is equivalent to: | |
| 453 * | |
| 454 * new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch, | |
| 455 * isUtc: false) | |
| 456 */ | |
| 457 DateTime toLocal() { | |
| 458 if (isUtc) { | |
| 459 return new DateTime._withValue(_value, isUtc: false); | |
| 460 } | |
| 461 return this; | |
| 462 } | |
| 463 | |
| 464 /** | |
| 465 * Returns this DateTime value in the UTC time zone. | |
| 466 * | |
| 467 * Returns [this] if it is already in UTC. | |
| 468 * Otherwise this method is equivalent to: | |
| 469 * | |
| 470 * new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch, | |
| 471 * isUtc: true) | |
| 472 */ | |
| 473 DateTime toUtc() { | |
| 474 if (isUtc) return this; | |
| 475 return new DateTime._withValue(_value, isUtc: true); | |
| 476 } | |
| 477 | |
| 478 static String _fourDigits(int n) { | |
| 479 int absN = n.abs(); | |
| 480 String sign = n < 0 ? "-" : ""; | |
| 481 if (absN >= 1000) return "$n"; | |
| 482 if (absN >= 100) return "${sign}0$absN"; | |
| 483 if (absN >= 10) return "${sign}00$absN"; | |
| 484 return "${sign}000$absN"; | |
| 485 } | |
| 486 | |
| 487 static String _sixDigits(int n) { | |
| 488 assert(n < -9999 || n > 9999); | |
| 489 int absN = n.abs(); | |
| 490 String sign = n < 0 ? "-" : "+"; | |
| 491 if (absN >= 100000) return "$sign$absN"; | |
| 492 return "${sign}0$absN"; | |
| 493 } | |
| 494 | |
| 495 static String _threeDigits(int n) { | |
| 496 if (n >= 100) return "${n}"; | |
| 497 if (n >= 10) return "0${n}"; | |
| 498 return "00${n}"; | |
| 499 } | |
| 500 | |
| 501 static String _twoDigits(int n) { | |
| 502 if (n >= 10) return "${n}"; | |
| 503 return "0${n}"; | |
| 504 } | |
| 505 | |
| 506 /** | |
| 507 * Returns a human-readable string for this instance. | |
| 508 * | |
| 509 * The returned string is constructed for the time zone of this instance. | |
| 510 * The `toString()` method provides a simply formatted string. | |
| 511 * It does not support internationalized strings. | |
| 512 * Use the [intl](http://pub.dartlang.org/packages/intl) package | |
| 513 * at the pub shared packages repo. | |
| 514 * | |
| 515 * The resulting string can be parsed back using [parse]. | |
| 516 */ | |
| 517 String toString() { | |
| 518 String y = _fourDigits(year); | |
| 519 String m = _twoDigits(month); | |
| 520 String d = _twoDigits(day); | |
| 521 String h = _twoDigits(hour); | |
| 522 String min = _twoDigits(minute); | |
| 523 String sec = _twoDigits(second); | |
| 524 String ms = _threeDigits(millisecond); | |
| 525 String us = microsecond == 0 ? "" : _threeDigits(microsecond); | |
| 526 if (isUtc) { | |
| 527 return "$y-$m-$d $h:$min:$sec.$ms${us}Z"; | |
| 528 } else { | |
| 529 return "$y-$m-$d $h:$min:$sec.$ms$us"; | |
| 530 } | |
| 531 } | |
| 532 | |
| 533 /** | |
| 534 * Returns an ISO-8601 full-precision extended format representation. | |
| 535 * | |
| 536 * The format is `yyyy-MM-ddTHH:mm:ss.mmmuuuZ` for UTC time, and | |
| 537 * `yyyy-MM-ddTHH:mm:ss.mmmuuu` (no trailing "Z") for local/non-UTC time, | |
| 538 * where: | |
| 539 * | |
| 540 * * `yyyy` is a, possibly negative, four digit representation of the year, | |
| 541 * if the year is in the range -9999 to 9999, | |
| 542 * otherwise it is a signed six digit representation of the year. | |
| 543 * * `MM` is the month in the range 01 to 12, | |
| 544 * * `dd` is the day of the month in the range 01 to 31, | |
| 545 * * `HH` are hours in the range 00 to 23, | |
| 546 * * `mm` are minutes in the range 00 to 59, | |
| 547 * * `ss` are seconds in the range 00 to 59 (no leap seconds), | |
| 548 * * `mmm` are milliseconds 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. | |
| 551 * | |
| 552 * The resulting string can be parsed back using [parse]. | |
| 553 */ | |
| 554 String toIso8601String() { | |
| 555 String y = (year >= -9999 && year <= 9999) ? _fourDigits(year) | |
| 556 : _sixDigits(year); | |
| 557 String m = _twoDigits(month); | |
| 558 String d = _twoDigits(day); | |
| 559 String h = _twoDigits(hour); | |
| 560 String min = _twoDigits(minute); | |
| 561 String sec = _twoDigits(second); | |
| 562 String ms = _threeDigits(millisecond); | |
| 563 String us = microsecond == 0 ? "" : _threeDigits(microsecond); | |
| 564 if (isUtc) { | |
| 565 return "$y-$m-${d}T$h:$min:$sec.$ms${us}Z"; | |
| 566 } else { | |
| 567 return "$y-$m-${d}T$h:$min:$sec.$ms$us"; | |
| 568 } | |
| 569 } | |
| 570 | |
| 571 /** | |
| 572 * Returns a new [DateTime] instance with [duration] added to [this]. | |
| 573 * | |
| 574 * DateTime today = new DateTime.now(); | |
| 575 * DateTime sixtyDaysFromNow = today.add(new Duration(days: 60)); | |
| 576 */ | |
| 577 external DateTime add(Duration duration); | |
| 578 | |
| 579 /** | |
| 580 * Returns a new [DateTime] instance with [duration] subtracted from [this]. | |
| 581 * | |
| 582 * DateTime today = new DateTime.now(); | |
| 583 * DateTime sixtyDaysAgo = today.subtract(new Duration(days: 30)); | |
| 584 * | |
| 585 * Notice that duration being subtracted is actually 30 * 24 * 60 * 60 seconds | |
| 586 * and if that crosses a daylight saving time change, the resulting `DateTime` | |
| 587 * won't have the same time of day as `today`, and may not actually hit the | |
| 588 * calendar date 30 days earlier. Be careful when working with dates in local | |
| 589 * time. | |
| 590 */ | |
| 591 external DateTime subtract(Duration duration); | |
| 592 | |
| 593 /** | |
| 594 * Returns a [Duration] with the difference between [this] and [other]. | |
| 595 * | |
| 596 * DateTime berlinWallFell = new DateTime.utc(1989, DateTime.NOVEMBER, 9); | |
| 597 * DateTime dDay = new DateTime.utc(1944, DateTime.JUNE, 6); | |
| 598 * | |
| 599 * Duration difference = berlinWallFell.difference(dDay); | |
| 600 * assert(difference.inDays == 16592); | |
| 601 * | |
| 602 * The difference is measured in seconds and fractions of seconds. | |
| 603 * The difference above counts the number of fractional seconds between | |
| 604 * midnight at the beginning of those dates. | |
| 605 * If the dates above had been in local time, not UTC, then the difference | |
| 606 * between two midnights may not be a multiple of 24 hours due to daylight | |
| 607 * saving differences. | |
| 608 * | |
| 609 * For example, in Australia, similar code using local time instead of UTC: | |
| 610 * | |
| 611 * DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9); | |
| 612 * DateTime dDay = new DateTime(1944, DateTime.JUNE, 6); | |
| 613 * Duration difference = berlinWallFell.difference(dDay); | |
| 614 * assert(difference.inDays == 16592); | |
| 615 * | |
| 616 * will fail because the difference is actually 16591 days and 23 hours, and | |
| 617 * [Duration.inDays] only returns the number of whole days. | |
| 618 */ | |
| 619 external Duration difference(DateTime other); | |
| 620 | |
| 621 external DateTime._internal(int year, | |
| 622 int month, | |
| 623 int day, | |
| 624 int hour, | |
| 625 int minute, | |
| 626 int second, | |
| 627 int millisecond, | |
| 628 int microsecond, | |
| 629 bool isUtc); | |
| 630 | |
| 631 external DateTime._now(); | |
| 632 | |
| 633 /// Returns the time as value (millisecond or microsecond since epoch), or | |
| 634 /// null if the values are out of range. | |
| 635 external static int _brokenDownDateToValue( | |
| 636 int year, int month, int day, int hour, int minute, int second, | |
| 637 int millisecond, int microsecond, bool isUtc); | |
| 638 | |
| 639 /** | |
| 640 * The number of milliseconds since | |
| 641 * the "Unix epoch" 1970-01-01T00:00:00Z (UTC). | |
| 642 * | |
| 643 * This value is independent of the time zone. | |
| 644 * | |
| 645 * This value is at most | |
| 646 * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch. | |
| 647 * In other words: `millisecondsSinceEpoch.abs() <= 8640000000000000`. | |
| 648 */ | |
| 649 external int get millisecondsSinceEpoch; | |
| 650 | |
| 651 /** | |
| 652 * The number of microseconds since | |
| 653 * the "Unix epoch" 1970-01-01T00:00:00Z (UTC). | |
| 654 * | |
| 655 * This value is independent of the time zone. | |
| 656 * | |
| 657 * This value is at most | |
| 658 * 8,640,000,000,000,000,000us (100,000,000 days) from the Unix epoch. | |
| 659 * In other words: `microsecondsSinceEpoch.abs() <= 8640000000000000000`. | |
| 660 * | |
| 661 * Note that this value does not fit into 53 bits (the size of a IEEE double). | |
| 662 * A JavaScript number is not able to hold this value. | |
| 663 */ | |
| 664 external int get microsecondsSinceEpoch; | |
| 665 | |
| 666 /** | |
| 667 * The abbreviated time zone name—for example, | |
| 668 * [:"CET":] or [:"CEST":]. | |
| 669 */ | |
| 670 external String get timeZoneName; | |
| 671 | |
| 672 /** | |
| 673 * The time zone offset, which | |
| 674 * is the difference between local time and UTC. | |
| 675 * | |
| 676 * The offset is positive for time zones east of UTC. | |
| 677 * | |
| 678 * Note, that JavaScript, Python and C return the difference between UTC and | |
| 679 * local time. Java, C# and Ruby return the difference between local time and | |
| 680 * UTC. | |
| 681 */ | |
| 682 external Duration get timeZoneOffset; | |
| 683 | |
| 684 /** | |
| 685 * The year. | |
| 686 * | |
| 687 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 688 * assert(moonLanding.year == 1969); | |
| 689 */ | |
| 690 external int get year; | |
| 691 | |
| 692 /** | |
| 693 * The month [1..12]. | |
| 694 * | |
| 695 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 696 * assert(moonLanding.month == 7); | |
| 697 * assert(moonLanding.month == DateTime.JULY); | |
| 698 */ | |
| 699 external int get month; | |
| 700 | |
| 701 /** | |
| 702 * The day of the month [1..31]. | |
| 703 * | |
| 704 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 705 * assert(moonLanding.day == 20); | |
| 706 */ | |
| 707 external int get day; | |
| 708 | |
| 709 /** | |
| 710 * The hour of the day, expressed as in a 24-hour clock [0..23]. | |
| 711 * | |
| 712 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 713 * assert(moonLanding.hour == 20); | |
| 714 */ | |
| 715 external int get hour; | |
| 716 | |
| 717 /** | |
| 718 * The minute [0...59]. | |
| 719 * | |
| 720 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 721 * assert(moonLanding.minute == 18); | |
| 722 */ | |
| 723 external int get minute; | |
| 724 | |
| 725 /** | |
| 726 * The second [0...59]. | |
| 727 * | |
| 728 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 729 * assert(moonLanding.second == 0); | |
| 730 */ | |
| 731 external int get second; | |
| 732 | |
| 733 /** | |
| 734 * The millisecond [0...999]. | |
| 735 * | |
| 736 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 737 * assert(moonLanding.millisecond == 0); | |
| 738 */ | |
| 739 external int get millisecond; | |
| 740 | |
| 741 /** | |
| 742 * The microsecond [0...999]. | |
| 743 * | |
| 744 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 745 * assert(moonLanding.microsecond == 0); | |
| 746 */ | |
| 747 external int get microsecond; | |
| 748 | |
| 749 /** | |
| 750 * The day of the week [MONDAY]..[SUNDAY]. | |
| 751 * | |
| 752 * In accordance with ISO 8601 | |
| 753 * a week starts with Monday, which has the value 1. | |
| 754 * | |
| 755 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | |
| 756 * assert(moonLanding.weekday == 7); | |
| 757 * assert(moonLanding.weekday == DateTime.SUNDAY); | |
| 758 * | |
| 759 */ | |
| 760 external int get weekday; | |
| 761 } | |
| OLD | NEW |