// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. part of "dart:core"; /// An instant in time, such as July 20, 1969, 8:18pm GMT. /// /// DateTimes can represent time values that are at a distance of at most /// 100,000,000 days from epoch (1970-01-01 UTC): -271821-04-20 to 275760-09-13. /// /// Create a `DateTime` object by using one of the constructors /// or by parsing a correctly formatted string, /// which complies with a subset of ISO 8601. /// **Note:** hours are specified between 0 and 23, /// as in a 24-hour clock. /// /// For example: /// ```dart /// final now = DateTime.now(); /// final berlinWallFell = DateTime.utc(1989, 11, 9); /// final moonLanding = DateTime.parse('1969-07-20 20:18:04Z'); // 8:18pm /// ``` /// /// A `DateTime` object is anchored either in the UTC time zone /// or in the local time zone of the current computer /// when the object is created. /// /// Once created, neither the value nor the time zone /// of a `DateTime` object may be changed. /// /// You can use properties to get /// the individual units of a `DateTime` object. /// ``` /// print(berlinWallFell.year); // 1989 /// print(berlinWallFell.month); // 11 /// print(berlinWallFell.day); // 9 /// print(moonLanding.hour); // 20 /// print(moonLanding.minute); // 18 /// ``` /// For convenience and readability, /// the `DateTime` class provides a constant for each `day` and `month` /// name - for example, [august] and [friday]. /// You can use these constants to improve code readability: /// ```dart /// final berlinWallFell = DateTime.utc(1989, DateTime.november, 9); /// print(DateTime.november); // 11 /// assert(berlinWallFell.month == DateTime.november); /// assert(berlinWallFell.weekday == DateTime.thursday); /// ``` /// /// `Day` and `month` values begin at 1, and the week starts on `Monday`. /// That is, the constants [january] and [monday] are both 1. /// /// ## Working with UTC and local time /// /// A `DateTime` object is in the local time zone /// unless explicitly created in the UTC time zone. /// Use [isUtc] to determine whether a `DateTime` object is based in UTC. /// /// ```dart /// final dDay = DateTime.utc(1944, 6, 6); /// print(dDay.isUtc); // true /// /// final dDayLocal = DateTime(1944, 6, 6); /// print(dDayLocal.isUtc); // false /// ``` /// Use the methods [toLocal] and [toUtc] /// to get the equivalent date/time value specified in the other time zone. /// ``` /// final localDay = dDay.toLocal(); // e.g. 1944-06-06 02:00:00.000 /// print(localDay.isUtc); // false /// /// final utcFromLocal = localDay.toUtc(); // 1944-06-06 00:00:00.000Z /// print(utcFromLocal.isUtc); // true /// ``` /// Use [timeZoneName] to get an abbreviated name of the time zone /// for the `DateTime` object. /// ``` /// print(dDay.timeZoneName); // UTC /// print(localDay.timeZoneName); // e.g. EET /// ``` /// To find the difference /// between UTC and the time zone of a `DateTime` object /// call [timeZoneOffset]. /// ``` /// print(dDay.timeZoneOffset); // 0:00:00.000000 /// print(localDay.timeZoneOffset); // e.g. 2:00:00.000000 /// ``` /// /// ## Comparing DateTime objects /// /// The `DateTime` class contains methods for comparing `DateTime`s /// chronologically, such as [isAfter], [isBefore], and [isAtSameMomentAs]. /// ``` /// print(berlinWallFell.isAfter(moonLanding)); // true /// print(berlinWallFell.isBefore(moonLanding)); // false /// print(dDay.isAtSameMomentAs(localDay)); // true /// ``` /// /// ## Using DateTime with Duration /// /// Use the [add] and [subtract] methods with a [Duration] object /// to create a `DateTime` object based on another. /// For example, to find the point in time that is 36 hours after now, /// you can write: /// ```dart /// final now = DateTime.now(); /// final later = now.add(const Duration(hours: 36)); /// ``` /// /// To find out how much time is between two `DateTime` objects use /// [difference], which returns a [Duration] object: /// ``` /// final difference = berlinWallFell.difference(moonLanding); /// print(difference.inDays); // 7416 /// ``` /// /// The difference between two dates in different time zones /// is just the number of nanoseconds between the two points in time. /// It doesn't take calendar days into account. /// That means that the difference between two midnights in local time may be /// less than 24 hours times the number of days between them, /// if there is a daylight saving change in between. /// If the difference above is calculated using Australian local time, the /// difference is 7415 days and 23 hours, which is only 7415 whole days as /// reported by `inDays`. /// /// ## Other resources /// /// * See [Duration] to represent a span of time. /// * See [Stopwatch] to measure timespans. /// * The `DateTime` class does not provide internationalization. /// To internationalize your code, use /// the [intl](https://pub.dev/packages/intl) package. class DateTime implements Comparable { // Weekday constants that are returned by [weekday] method: static const int monday = 1; static const int tuesday = 2; static const int wednesday = 3; static const int thursday = 4; static const int friday = 5; static const int saturday = 6; static const int sunday = 7; static const int daysPerWeek = 7; // Month constants that are returned by the [month] getter. static const int january = 1; static const int february = 2; static const int march = 3; static const int april = 4; static const int may = 5; static const int june = 6; static const int july = 7; static const int august = 8; static const int september = 9; static const int october = 10; static const int november = 11; static const int december = 12; static const int monthsPerYear = 12; /// True if this [DateTime] is set to UTC time. /// /// ```dart /// final dDay = DateTime.utc(1944, 6, 6); /// print(dDay.isUtc); // true /// /// final local = DateTime(1944, 6, 6); /// print(local.isUtc); // false /// ``` final bool isUtc; /// Constructs a [DateTime] instance specified in the local time zone. /// /// For example, /// to create a `DateTime` object representing the 7th of September 2017, /// 5:30pm /// /// ```dart /// final dentistAppointment = DateTime(2017, 9, 7, 17, 30); /// ``` DateTime( int year, [ int month = 1, int day = 1, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0, ]) : this._internal( year, month, day, hour, minute, second, millisecond, microsecond, false, ); /// Constructs a [DateTime] instance specified in the UTC time zone. /// /// ```dart /// final moonLanding = DateTime.utc(1969, 7, 20, 20, 18, 04); /// ``` /// /// When dealing with dates or historic events, preferably use UTC DateTimes, /// since they are unaffected by daylight-saving changes and are unaffected /// by the local timezone. DateTime.utc( int year, [ int month = 1, int day = 1, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0, ]) : this._internal( year, month, day, hour, minute, second, millisecond, microsecond, true, ); /// Constructs a [DateTime] instance with current date and time in the /// local time zone. /// /// ```dart /// final now = DateTime.now(); /// ``` DateTime.now() : this._now(); /// Constructs a [DateTime] with the current UTC date and time. /// /// /// ```dart /// final mark = DateTime.timestamp(); /// ``` @Since("3.0") DateTime.timestamp() : this._nowUtc(); external DateTime._nowUtc(); /// Constructs a new [DateTime] instance based on [formattedString]. /// /// Throws a [FormatException] if the input string cannot be parsed. /// /// The function parses a subset of ISO 8601, /// which includes the subset accepted by RFC 3339. /// /// The accepted inputs are currently: /// /// * A date: A signed four-to-six digit year, two digit month and /// two digit day, optionally separated by `-` characters. /// Examples: "19700101", "-0004-12-24", "81030-04-01". /// * An optional time part, separated from the date by either `T` or a space. /// The time part is a two digit hour, /// then optionally a two digit minutes value, /// then optionally a two digit seconds value, and /// then optionally a '.' or ',' followed by at least a one digit /// second fraction. /// The minutes and seconds may be separated from the previous parts by a /// ':'. /// Examples: "12", "12:30:24.124", "12:30:24,124", "123010.50". /// * An optional time-zone offset part, /// possibly separated from the previous by a space. /// The time zone is either 'z' or 'Z', or it is a signed two digit hour /// part and an optional two digit minute part. The sign must be either /// "+" or "-", and cannot be omitted. /// The minutes may be separated from the hours by a ':'. /// Examples: "Z", "-10", "+01:30", "+1130". /// /// This includes the output of both [toString] and [toIso8601String], which /// will be parsed back into a `DateTime` object with the same time as the /// original. /// /// The result is always in either local time or UTC. /// If a time zone offset other than UTC is specified, /// the time is converted to the equivalent UTC time. /// /// Examples of accepted strings: /// /// * `"2012-02-27"` /// * `"2012-02-27 13:27:00"` /// * `"2012-02-27 13:27:00.123456789z"` /// * `"2012-02-27 13:27:00,123456789z"` /// * `"20120227 13:27:00"` /// * `"20120227T132700"` /// * `"20120227"` /// * `"+20120227"` /// * `"2012-02-27T14Z"` /// * `"2012-02-27T14+00:00"` /// * `"-123450101 00:00:00 Z"`: in the year -12345. /// * `"2002-02-27T14:00:00-0500"`: Same as `"2002-02-27T19:00:00Z"` /// /// This method accepts out-of-range component values and interprets /// them as overflows into the next larger component. /// For example, "2020-01-42" will be parsed as 2020-02-11, because /// the last valid date in that month is 2020-01-31, so 42 days is /// interpreted as 31 days of that month plus 11 days into the next month. /// /// To detect and reject invalid component values, use /// [DateFormat.parseStrict](https://pub.dev/documentation/intl/latest/intl/DateFormat/parseStrict.html) /// from the [intl](https://pub.dev/packages/intl) package. static DateTime parse(String formattedString) { var re = _parseFormat; Match? match = re.firstMatch(formattedString); if (match != null) { int parseIntOrZero(String? matched) { if (matched == null) return 0; return int.parse(matched); } // Parses fractional second digits of '.(\d+)' into the combined // microseconds. We only use the first 6 digits because of DateTime // precision of 999 milliseconds and 999 microseconds. int parseMilliAndMicroseconds(String? matched) { if (matched == null) return 0; int length = matched.length; assert(length >= 1); int result = 0; for (int i = 0; i < 6; i++) { result *= 10; if (i < matched.length) { result += matched.codeUnitAt(i) ^ 0x30; } } return result; } int years = int.parse(match[1]!); int month = int.parse(match[2]!); int day = int.parse(match[3]!); int hour = parseIntOrZero(match[4]); int minute = parseIntOrZero(match[5]); int second = parseIntOrZero(match[6]); int milliAndMicroseconds = parseMilliAndMicroseconds(match[7]); int millisecond = milliAndMicroseconds ~/ Duration.microsecondsPerMillisecond; int microsecond = milliAndMicroseconds.remainder(Duration.microsecondsPerMillisecond) as int; bool isUtc = false; if (match[8] != null) { // timezone part isUtc = true; String? tzSign = match[9]; if (tzSign != null) { // timezone other than 'Z' and 'z'. int sign = (tzSign == '-') ? -1 : 1; int hourDifference = int.parse(match[10]!); int minuteDifference = parseIntOrZero(match[11]); minuteDifference += 60 * hourDifference; minute -= sign * minuteDifference; } } DateTime? result = _finishParse( years, month, day, hour, minute, second, millisecond, microsecond, isUtc, ); if (result == null) { throw FormatException("Time out of range", formattedString); } return result; } else { throw FormatException("Invalid date format", formattedString); } } /// Constructs a new [DateTime] instance based on [formattedString]. /// /// Works like [parse] except that this function returns `null` /// where [parse] would throw a [FormatException]. static DateTime? tryParse(String formattedString) { // TODO: Optimize to avoid throwing. try { return parse(formattedString); } on FormatException { return null; } } static const int _maxMillisecondsSinceEpoch = 8640000000000000; static const int _maxMicrosecondsSinceEpoch = _maxMillisecondsSinceEpoch * Duration.microsecondsPerMillisecond; /// Constructs a new [DateTime] instance /// with the given [millisecondsSinceEpoch]. /// /// If [isUtc] is false then the date is in the local time zone. /// /// The constructed [DateTime] represents /// 1970-01-01T00:00:00Z + [millisecondsSinceEpoch] ms in the given /// time zone (local or UTC). /// ```dart /// final newYearsDay = /// DateTime.fromMillisecondsSinceEpoch(1641031200000, isUtc:true); /// print(newYearsDay); // 2022-01-01 10:00:00.000Z /// ``` external DateTime.fromMillisecondsSinceEpoch( int millisecondsSinceEpoch, { bool isUtc = false, }); /// Constructs a new [DateTime] instance /// with the given [microsecondsSinceEpoch]. /// /// If [isUtc] is false, then the date is in the local time zone. /// /// The constructed [DateTime] represents /// 1970-01-01T00:00:00Z + [microsecondsSinceEpoch] us in the given /// time zone (local or UTC). /// ```dart /// final newYearsEve = /// DateTime.fromMicrosecondsSinceEpoch(1640979000000000, isUtc:true); /// print(newYearsEve); // 2021-12-31 19:30:00.000Z /// ``` external DateTime.fromMicrosecondsSinceEpoch( int microsecondsSinceEpoch, { bool isUtc = false, }); /// Throws an error if the millisecondsSinceEpoch and microsecond components /// are out of range. /// /// Returns the millisecondsSinceEpoch component. static int _validate( int millisecondsSinceEpoch, int microsecond, bool isUtc, ) { if (microsecond < 0 || microsecond > 999) { throw RangeError.range(microsecond, 0, 999, "microsecond"); } if (millisecondsSinceEpoch < -_maxMillisecondsSinceEpoch || millisecondsSinceEpoch > _maxMillisecondsSinceEpoch) { throw RangeError.range( millisecondsSinceEpoch, -_maxMillisecondsSinceEpoch, _maxMillisecondsSinceEpoch, "millisecondsSinceEpoch", ); } if (millisecondsSinceEpoch == _maxMillisecondsSinceEpoch && microsecond != 0) { throw ArgumentError.value( microsecond, "microsecond", "Time including microseconds is outside valid range", ); } // For backwards compatibility with legacy mode. checkNotNullable(isUtc, "isUtc"); return millisecondsSinceEpoch; } /// Whether [other] is a [DateTime] at the same moment and in the /// same time zone (UTC or local). /// /// ```dart /// final dDayUtc = DateTime.utc(1944, 6, 6); /// final dDayLocal = dDayUtc.toLocal(); /// /// // These two dates are at the same moment, but are in different zones. /// assert(dDayUtc != dDayLocal); /// print(dDayUtc != dDayLocal); // true /// ``` /// /// See [isAtSameMomentAs] for a comparison that compares moments in time /// independently of their zones. external bool operator ==(Object other); external int get hashCode; /// Whether this [DateTime] occurs before [other]. /// /// The comparison is independent /// of whether the time is in UTC or in the local time zone. /// /// ```dart /// final now = DateTime.now(); /// final earlier = now.subtract(const Duration(seconds: 5)); /// print(earlier.isBefore(now)); // true /// print(!now.isBefore(now)); // true /// /// // This relation stays the same, even when changing timezones. /// print(earlier.isBefore(now.toUtc())); // true /// print(earlier.toUtc().isBefore(now)); // true /// /// print(!now.toUtc().isBefore(now)); // true /// print(!now.isBefore(now.toUtc())); // true /// ``` external bool isBefore(DateTime other); /// Whether this [DateTime] occurs after [other]. /// /// The comparison is independent /// of whether the time is in UTC or in the local time zone. /// /// ```dart /// final now = DateTime.now(); /// final later = now.add(const Duration(seconds: 5)); /// print(later.isAfter(now)); // true /// print(!now.isBefore(now)); // true /// /// // This relation stays the same, even when changing timezones. /// print(later.isAfter(now.toUtc())); // true /// print(later.toUtc().isAfter(now)); // true /// /// print(!now.toUtc().isAfter(now)); // true /// print(!now.isAfter(now.toUtc())); // true /// ``` external bool isAfter(DateTime other); /// Whether this [DateTime] occurs at the same moment as [other]. /// /// The comparison is independent of whether the time is in UTC or in the local /// time zone. /// /// ```dart /// final now = DateTime.now(); /// final later = now.add(const Duration(seconds: 5)); /// print(!later.isAtSameMomentAs(now)); // true /// print(now.isAtSameMomentAs(now)); // true /// /// // This relation stays the same, even when changing timezones. /// print(!later.isAtSameMomentAs(now.toUtc())); // true /// print(!later.toUtc().isAtSameMomentAs(now)); // true /// /// print(now.toUtc().isAtSameMomentAs(now)); // true /// print(now.isAtSameMomentAs(now.toUtc())); // true /// ``` external bool isAtSameMomentAs(DateTime other); /// Compares this DateTime object to [other], /// returning zero if the values are equal. /// /// A [compareTo] function returns: /// * a negative value if this DateTime [isBefore] [other]. /// * `0` if this DateTime [isAtSameMomentAs] [other], and /// * a positive value otherwise (when this DateTime [isAfter] [other]). /// /// ```dart /// final now = DateTime.now(); /// final future = now.add(const Duration(days: 2)); /// final past = now.subtract(const Duration(days: 2)); /// final newDate = now.toUtc(); /// /// print(now.compareTo(future)); // -1 /// print(now.compareTo(past)); // 1 /// print(now.compareTo(newDate)); // 0 /// ``` external int compareTo(DateTime other); /// Returns this DateTime value in the local time zone. /// /// Returns this [DateTime] if it is already in the local time zone. /// Otherwise this method is equivalent to: /// /// ```dart template:expression /// DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch, /// isUtc: false) /// ``` DateTime toLocal() { if (isUtc) { return _withUtc(isUtc: false); } return this; } /// Returns this DateTime value in the UTC time zone. /// /// Returns this [DateTime] if it is already in UTC. /// Otherwise this method is equivalent to: /// /// ```dart template:expression /// DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch, /// isUtc: true) /// ``` DateTime toUtc() { if (isUtc) return this; return _withUtc(isUtc: true); } external DateTime _withUtc({required bool isUtc}); static String _fourDigits(int n) { int absN = n.abs(); String sign = n < 0 ? "-" : ""; if (absN >= 1000) return "$n"; if (absN >= 100) return "${sign}0$absN"; if (absN >= 10) return "${sign}00$absN"; return "${sign}000$absN"; } static String _sixDigits(int n) { assert(n < -9999 || n > 9999); int absN = n.abs(); String sign = n < 0 ? "-" : "+"; if (absN >= 100000) return "$sign$absN"; return "${sign}0$absN"; } static String _threeDigits(int n) { if (n >= 100) return "${n}"; if (n >= 10) return "0${n}"; return "00${n}"; } static String _twoDigits(int n) { if (n >= 10) return "${n}"; return "0${n}"; } /// Returns a human-readable string for this instance. /// /// The returned string is constructed for the time zone of this instance. /// The `toString()` method provides a simply formatted string. /// It does not support internationalized strings. /// Use the [intl](https://pub.dev/packages/intl) package /// at the pub shared packages repo. /// /// The resulting string can be parsed back using [parse]. String toString() { String y = _fourDigits(year); String m = _twoDigits(month); String d = _twoDigits(day); String h = _twoDigits(hour); String min = _twoDigits(minute); String sec = _twoDigits(second); String ms = _threeDigits(millisecond); String us = microsecond == 0 ? "" : _threeDigits(microsecond); if (isUtc) { return "$y-$m-$d $h:$min:$sec.$ms${us}Z"; } else { return "$y-$m-$d $h:$min:$sec.$ms$us"; } } /// Returns an ISO-8601 full-precision extended format representation. /// /// The format is `yyyy-MM-ddTHH:mm:ss.mmmuuuZ` for UTC time, and /// `yyyy-MM-ddTHH:mm:ss.mmmuuu` (no trailing "Z") for local/non-UTC time, /// where: /// /// * `yyyy` is a, possibly negative, four digit representation of the year, /// if the year is in the range -9999 to 9999, /// otherwise it is a signed six digit representation of the year. /// * `MM` is the month in the range 01 to 12, /// * `dd` is the day of the month in the range 01 to 31, /// * `HH` are hours in the range 00 to 23, /// * `mm` are minutes in the range 00 to 59, /// * `ss` are seconds in the range 00 to 59 (no leap seconds), /// * `mmm` are milliseconds in the range 000 to 999, and /// * `uuu` are microseconds in the range 001 to 999. If [microsecond] equals /// 0, then this part is omitted. /// /// The resulting string can be parsed back using [parse]. /// ```dart /// final moonLanding = DateTime.utc(1969, 7, 20, 20, 18, 04); /// final isoDate = moonLanding.toIso8601String(); /// print(isoDate); // 1969-07-20T20:18:04.000Z /// ``` String toIso8601String() { String y = (year >= -9999 && year <= 9999) ? _fourDigits(year) : _sixDigits(year); String m = _twoDigits(month); String d = _twoDigits(day); String h = _twoDigits(hour); String min = _twoDigits(minute); String sec = _twoDigits(second); String ms = _threeDigits(millisecond); String us = microsecond == 0 ? "" : _threeDigits(microsecond); if (isUtc) { return "$y-$m-${d}T$h:$min:$sec.$ms${us}Z"; } else { return "$y-$m-${d}T$h:$min:$sec.$ms$us"; } } /// Returns a new [DateTime] instance with [duration] added to this [DateTime]. /// /// ```dart /// final today = DateTime.now(); /// final fiftyDaysFromNow = today.add(const Duration(days: 50)); /// ``` /// /// Notice that the duration being added is actually 50 * 24 * 60 * 60 /// seconds. If the resulting `DateTime` has a different daylight saving offset /// than `this`, then the result won't have the same time-of-day as `this`, and /// may not even hit the calendar date 50 days later. /// /// Be careful when working with dates in local time. external DateTime add(Duration duration); /// Returns a new [DateTime] instance with [duration] subtracted from this /// [DateTime]. /// /// ```dart /// final today = DateTime.now(); /// final fiftyDaysAgo = today.subtract(const Duration(days: 50)); /// ``` /// /// Notice that the duration being subtracted is actually 50 * 24 * 60 * 60 /// seconds. If the resulting `DateTime` has a different daylight saving offset /// than `this`, then the result won't have the same time-of-day as `this`, and /// may not even hit the calendar date 50 days earlier. /// /// Be careful when working with dates in local time. external DateTime subtract(Duration duration); /// Returns a [Duration] with the difference when subtracting [other] from /// this [DateTime]. /// /// The returned [Duration] will be negative if [other] occurs after this /// [DateTime]. /// /// ```dart /// final berlinWallFell = DateTime.utc(1989, DateTime.november, 9); /// final dDay = DateTime.utc(1944, DateTime.june, 6); /// /// final difference = berlinWallFell.difference(dDay); /// print(difference.inDays); // 16592 /// ``` /// /// The difference is measured in seconds and fractions of seconds. /// The difference above counts the number of fractional seconds between /// midnight at the beginning of those dates. /// If the dates above had been in local time, not UTC, then the difference /// between two midnights may not be a multiple of 24 hours due to daylight /// saving differences. /// /// For example, in Australia, similar code using local time instead of UTC: /// /// ```dart /// final berlinWallFell = DateTime(1989, DateTime.november, 9); /// final dDay = DateTime(1944, DateTime.june, 6); /// final difference = berlinWallFell.difference(dDay); /// print(difference.inDays); // 16591 /// assert(difference.inDays == 16592); /// ``` /// will fail because the difference is actually 16591 days and 23 hours, and /// [Duration.inDays] only returns the number of whole days. external Duration difference(DateTime other); external DateTime._internal( int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, bool isUtc, ); external DateTime._now(); /// Returns the [DateTime] corresponding to the given components, or `null` if /// the values are out of range. external static DateTime? _finishParse( int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, bool isUtc, ); /// The number of milliseconds since /// the "Unix epoch" 1970-01-01T00:00:00Z (UTC). /// /// This value is independent of the time zone. /// /// This value is at most /// 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch. /// In other words: `millisecondsSinceEpoch.abs() <= 8640000000000000`. external int get millisecondsSinceEpoch; /// The number of microseconds since /// the "Unix epoch" 1970-01-01T00:00:00Z (UTC). /// /// This value is independent of the time zone. /// /// This value is at most /// 8,640,000,000,000,000,000us (100,000,000 days) from the Unix epoch. /// In other words: `microsecondsSinceEpoch.abs() <= 8640000000000000000`. /// /// Note that this value does not always fit into 53 bits (the size of a IEEE /// double). On the web JavaScript platforms, there may be a rounding error /// for DateTime values sufficiently far from the epoch. The year range close /// to the epoch to avoid rounding is approximately 1685..2254. external int get microsecondsSinceEpoch; /// The time zone name. /// /// This value is provided by the operating system and may be an /// abbreviation or a full name. /// /// In the browser or on Unix-like systems commonly returns abbreviations, /// such as "CET" or "CEST". On Windows returns the full name, for example /// "Pacific Standard Time". external String get timeZoneName; /// The time zone offset, which /// is the difference between local time and UTC. /// /// The offset is positive for time zones east of UTC. /// /// Note, that JavaScript, Python and C return the difference between UTC and /// local time. Java, C# and Ruby return the difference between local time and /// UTC. /// /// For example, using local time in San Francisco, United States: /// ```dart /// final dateUS = DateTime.parse('2021-11-01 20:18:04Z').toLocal(); /// print(dateUS); // 2021-11-01 13:18:04.000 /// print(dateUS.timeZoneName); // PDT ( Pacific Daylight Time ) /// print(dateUS.timeZoneOffset.inHours); // -7 /// print(dateUS.timeZoneOffset.inMinutes); // -420 /// ``` /// /// For example, using local time in Canberra, Australia: /// ```dart /// final dateAus = DateTime.parse('2021-11-01 20:18:04Z').toLocal(); /// print(dateAus); // 2021-11-02 07:18:04.000 /// print(dateAus.timeZoneName); // AEDT ( Australian Eastern Daylight Time ) /// print(dateAus.timeZoneOffset.inHours); // 11 /// print(dateAus.timeZoneOffset.inMinutes); // 660 /// ``` external Duration get timeZoneOffset; /// The year. /// /// ```dart /// final moonLanding = DateTime.parse('1969-07-20 20:18:04Z'); /// print(moonLanding.year); // 1969 /// ``` external int get year; /// The month `[1..12]`. /// /// ```dart /// final moonLanding = DateTime.parse('1969-07-20 20:18:04Z'); /// print(moonLanding.month); // 7 /// assert(moonLanding.month == DateTime.july); /// ``` external int get month; /// The day of the month `[1..31]`. /// /// ```dart /// final moonLanding = DateTime.parse('1969-07-20 20:18:04Z'); /// print(moonLanding.day); // 20 /// ``` external int get day; /// The hour of the day, expressed as in a 24-hour clock `[0..23]`. /// /// ```dart /// final moonLanding = DateTime.parse('1969-07-20 20:18:04Z'); /// print(moonLanding.hour); // 20 /// ``` external int get hour; /// The minute `[0...59]`. /// /// ```dart /// final moonLanding = DateTime.parse('1969-07-20 20:18:04Z'); /// print(moonLanding.minute); // 18 /// ``` external int get minute; /// The second `[0...59]`. /// /// ```dart /// final moonLanding = DateTime.parse('1969-07-20 20:18:04Z'); /// print(moonLanding.second); // 4 /// ``` external int get second; /// The millisecond `[0...999]`. /// /// ```dart /// final date = DateTime.parse('1970-01-01 05:01:01.234567Z'); /// print(date.millisecond); // 234 /// ``` external int get millisecond; /// The microsecond `[0...999]`. /// /// ```dart /// final date = DateTime.parse('1970-01-01 05:01:01.234567Z'); /// print(date.microsecond); // 567 /// ``` external int get microsecond; /// The day of the week [monday]..[sunday]. /// /// In accordance with ISO 8601 /// a week starts with Monday, which has the value 1. /// /// ```dart /// final moonLanding = DateTime.parse('1969-07-20 20:18:04Z'); /// print(moonLanding.weekday); // 7 /// assert(moonLanding.weekday == DateTime.sunday); /// ``` external int get weekday; /* * date ::= yeardate time_opt timezone_opt * yeardate ::= year colon_opt month colon_opt day * year ::= sign_opt digit{4,6} * colon_opt ::= | ':' * sign ::= '+' | '-' * sign_opt ::= | sign * month ::= digit{2} * day ::= digit{2} * time_opt ::= | (' ' | 'T') hour minutes_opt * minutes_opt ::= | colon_opt digit{2} seconds_opt * seconds_opt ::= | colon_opt digit{2} millis_opt * micros_opt ::= | ('.' | ',') digit+ * timezone_opt ::= | space_opt timezone * space_opt ::= ' ' | * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt * timezonemins_opt ::= | colon_opt digit{2} */ static final RegExp _parseFormat = RegExp( r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // Day part. r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d+))?)?)?' // Time part. r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$', ); // Timezone part. } /// Adds [copyWith] method to [DateTime] objects. @Since("2.19") extension DateTimeCopyWith on DateTime { /// Creates a new [DateTime] from this one by updating individual properties. /// /// The [copyWith] method creates a new [DateTime] object with values /// for the properties [DateTime.year], [DateTime.hour], etc, provided by /// similarly named arguments, or using the existing value of the property /// if no argument, or `null`, is provided. /// /// Example: /// ```dart /// final now = DateTime.now(); /// final sameTimeOnMoonLandingDay = /// now.copyWith(year: 1969, month: 07, day: 20); /// ``` /// /// Like for the [DateTime] and [DateTime.utc] constructors, /// which this operation uses to create the new value, /// property values are allowed to overflow or underflow the range /// of the property (like a [month] outside the 1 to 12 range), /// which can affect the more significant properties /// (for example, a month of 13 will result in the month of January /// of the next year.) /// /// Notice also that if the result is a local-time DateTime, /// seasonal time-zone adjustments (daylight saving) can cause some /// combinations of dates, hours and minutes to not exist, or to exist /// more than once. /// In the former case, a corresponding time in one of the two adjacent time /// zones is used instead. In the latter, one of the two options is chosen. DateTime copyWith({ int? year, int? month, int? day, int? hour, int? minute, int? second, int? millisecond, int? microsecond, bool? isUtc, }) { return ((isUtc ?? this.isUtc) ? DateTime.utc : DateTime.new)( year ?? this.year, month ?? this.month, day ?? this.day, hour ?? this.hour, minute ?? this.minute, second ?? this.second, millisecond ?? this.millisecond, microsecond ?? this.microsecond, ); } }