diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cb53543e6a..9415b343d92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ #### `dart:core` - Added `bool.parse` and `bool.tryParse` static methods. +- Added `DateTime.timestamp()` constructor to get current time as UTC. - **Breaking change** [#49529][]: - Removed the deprecated `List` constructor, as it wasn't null safe. diff --git a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart index fdcf03e6aa8..8fde4e44488 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart @@ -373,6 +373,11 @@ class DateTime { : isUtc = false, _value = Primitives.dateNow(); + @patch + DateTime._nowUtc() + : isUtc = true, + _value = Primitives.dateNow(); + /// Rounds the given [microsecond] to the nearest milliseconds value. /// /// For example, invoked with argument `2600` returns `3`. diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart index ae38294e450..7a6b5747f66 100644 --- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart @@ -280,6 +280,11 @@ class DateTime { : isUtc = false, _value = Primitives.dateNow(); + @patch + DateTime._nowUtc() + : isUtc = true, + _value = Primitives.dateNow(); + /// Rounds the given [microsecond] to the nearest milliseconds value. /// /// For example, invoked with argument `2600` returns `3`. diff --git a/sdk/lib/_internal/vm_shared/lib/date_patch.dart b/sdk/lib/_internal/vm_shared/lib/date_patch.dart index 8daa59b3ee5..d9be6ff208f 100644 --- a/sdk/lib/_internal/vm_shared/lib/date_patch.dart +++ b/sdk/lib/_internal/vm_shared/lib/date_patch.dart @@ -66,6 +66,11 @@ class DateTime { : isUtc = false, _value = _getCurrentMicros(); + @patch + DateTime._nowUtc() + : isUtc = true, + _value = _getCurrentMicros(); + @patch String get timeZoneName { if (isUtc) return "UTC"; diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart index 103e4e68acb..d7a8a6b9a95 100644 --- a/sdk/lib/core/date_time.dart +++ b/sdk/lib/core/date_time.dart @@ -225,6 +225,14 @@ class DateTime implements Comparable { /// ``` DateTime.now() : this._now(); + /// Constructs a [DateTime] with the current UTC date and time. + /// + /// + /// ```dart + /// final mark = DateTime.timestamp(); + /// ``` + DateTime.timestamp() : this._nowUtc(); + /// Constructs a new [DateTime] instance based on [formattedString]. /// /// Throws a [FormatException] if the input string cannot be parsed. diff --git a/tests/corelib/date_time_test.dart b/tests/corelib/date_time_test.dart index 21859ef50ef..63e8136c0f3 100644 --- a/tests/corelib/date_time_test.dart +++ b/tests/corelib/date_time_test.dart @@ -30,6 +30,45 @@ void testNow() { Expect.isFalse(t1.isUtc); } +void testTimestamp() { + // Assume `DateTime.now` works. + const int N = 1000000; + var nowBefore = DateTime.now(); + var timestamp = DateTime.timestamp(); + var iterations = 0; + while (true) { + // Test that `timestamp` is using the same "current time" as `now`. + Expect.isTrue(timestamp.isUtc, "Is UTC"); + Expect.isTrue( + nowBefore.microsecondsSinceEpoch <= timestamp.microsecondsSinceEpoch, + "After an earlier now"); + + var laterNow = DateTime.now(); + Expect.isTrue( + timestamp.microsecondsSinceEpoch <= laterNow.microsecondsSinceEpoch, + "Before a later now"); + + var newTimestamp = DateTime.timestamp(); + + // Succeed if time has also progressed. + if (timestamp.microsecondsSinceEpoch < + newTimestamp.microsecondsSinceEpoch) { + break; + } + // Otherwise emit diagnostics occasionally, until the test times out + // or succeeds. Which should be in at most a few milliseconds if all + // is well. + if (++iterations >= N) { + print("testTimestamp: No DateTime.timestamp() progress in $N loops." + "Time: $timestamp"); + iterations = 0; + } + + nowBefore = laterNow; + timestamp = newTimestamp; + } +} + void testMillisecondsSinceEpoch() { var dt1 = new DateTime.now(); var millisecondsSinceEpoch = dt1.millisecondsSinceEpoch; @@ -1218,6 +1257,7 @@ void testRegression46966() { void main() { testNow(); + testTimestamp(); testMillisecondsSinceEpoch(); testMicrosecondsSinceEpoch(); testConstructors();