From febb1929cd4dccd08232657890f935bd752866d4 Mon Sep 17 00:00:00 2001 From: Riley Porter Date: Sat, 26 Sep 2020 01:11:54 +0000 Subject: [PATCH] [ddc] Copy JS 2-digit year handling from dart2js. Fixes https://github.com/dart-lang/sdk/issues/42894 Change-Id: I68a8782d123c299ec34bfd0a31b3108138dac117 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164681 Reviewed-by: Riley Porter Reviewed-by: Nicholas Shahan Commit-Queue: Riley Porter --- .../js_dev_runtime/private/js_helper.dart | 8 ++++++++ tests/corelib/date_time_js_modified_test.dart | 16 ++++++++++++++++ tests/corelib_2/date_time_js_modified_test.dart | 16 ++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 tests/corelib/date_time_js_modified_test.dart create mode 100644 tests/corelib_2/date_time_js_modified_test.dart diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart index 11a3a8eee71..83815d94b10 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart @@ -354,6 +354,14 @@ class Primitives { @nullCheck bool isUtc) { final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000; var jsMonth = month - 1; + // The JavaScript Date constructor 'corrects' year NN to 19NN. Sidestep that + // correction by adjusting years out of that range and compensating with an + // adjustment of months. This hack should not be sensitive to leap years but + // use 400 just in case. + if (0 <= years && years < 100) { + years += 400; + jsMonth -= 400 * 12; + } int value; if (isUtc) { value = JS('!', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, diff --git a/tests/corelib/date_time_js_modified_test.dart b/tests/corelib/date_time_js_modified_test.dart new file mode 100644 index 00000000000..92f4b77dc34 --- /dev/null +++ b/tests/corelib/date_time_js_modified_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2020, 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. + +import "package:expect/expect.dart"; + +// The JavaScript Date constructor 'corrects' 2-digit years NN to 19NN. +// Verify that a DateTime with year 1 is created correctly. +// Regression test for https://github.com/dart-lang/sdk/issues/42894 + +main() { + var d = new DateTime(1, 0, 1, 0, 0, 0, 0); + var d2 = new DateTime(0, 12, 1, 0, 0, 0, 0); + + Expect.equals(d, d2); +} diff --git a/tests/corelib_2/date_time_js_modified_test.dart b/tests/corelib_2/date_time_js_modified_test.dart new file mode 100644 index 00000000000..92f4b77dc34 --- /dev/null +++ b/tests/corelib_2/date_time_js_modified_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2020, 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. + +import "package:expect/expect.dart"; + +// The JavaScript Date constructor 'corrects' 2-digit years NN to 19NN. +// Verify that a DateTime with year 1 is created correctly. +// Regression test for https://github.com/dart-lang/sdk/issues/42894 + +main() { + var d = new DateTime(1, 0, 1, 0, 0, 0, 0); + var d2 = new DateTime(0, 12, 1, 0, 0, 0, 0); + + Expect.equals(d, d2); +}