mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 09:31:58 +00:00
2228b6d337
Change-Id: I7ac31a6bf66c777202a6c642bae584af8e3288ab Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/140380 Reviewed-by: Bob Nystrom <rnystrom@google.com> Commit-Queue: Mark Zhou <markzipan@google.com>
139 lines
5.1 KiB
Dart
139 lines
5.1 KiB
Dart
// Copyright (c) 2017, 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";
|
|
|
|
// Make sure that date-times close to daylight savings work correctly.
|
|
// See http://dartbug.com/30550
|
|
|
|
/// A list of (decomposed) date-times where daylight saving changes
|
|
/// happen.
|
|
///
|
|
/// This list covers multiple timezones to increase test coverage on
|
|
/// different machines.
|
|
final daylightSavingChanges = [
|
|
// TZ environment, y, m, d, h, change.
|
|
["Europe/Paris", 2017, 03, 26, 02, 60],
|
|
["Europe/Paris", 2017, 10, 29, 03, -60],
|
|
["Antarctica/Troll", 2017, 03, 19, 01, 120],
|
|
["Antarctica/Troll", 2017, 10, 29, 03, -120],
|
|
["Australia/Canberra", 2017, 04, 02, 03, -60],
|
|
["Australia/Canberra", 2017, 10, 01, 02, 60],
|
|
["Australia/Lord_Howe", 2017, 04, 02, 02, -30],
|
|
["Australia/Lord_Howe", 2017, 10, 01, 02, 30],
|
|
["Atlantic/Bermuda", 2017, 03, 12, 02, 60], // US and Canada.
|
|
["Atlantic/Bermuda", 2017, 11, 05, 02, -60],
|
|
["America/Campo_Grande", 2017, 02, 19, 00, -60], // Brazil
|
|
["America/Campo_Grande", 2017, 10, 15, 00, 60],
|
|
["America/Santiago", 2017, 05, 14, 00, -60],
|
|
["America/Santiago", 2017, 08, 13, 00, 60],
|
|
["Chile/EasterIsland", 2017, 05, 13, 22, -60],
|
|
["Chile/EasterIsland", 2017, 08, 12, 22, 60],
|
|
["Pacific/Fiji", 2017, 01, 15, 03, -60],
|
|
["Pacific/Fiji", 2017, 11, 05, 02, 60],
|
|
["America/Scoresbysund", 2017, 03, 26, 00, 60], // Ittoqqortoormiit.
|
|
["America/Scoresbysund", 2017, 10, 29, 01, -60],
|
|
["Asia/Tehran", 2017, 03, 22, 00, 60],
|
|
["Asia/Tehran", 2017, 09, 22, 00, -60],
|
|
["Israel", 2017, 03, 24, 02, 60],
|
|
["Israel", 2017, 10, 29, 02, -60],
|
|
["Asia/Amman", 2017, 03, 31, 00, 60],
|
|
["Asia/Amman", 2017, 10, 27, 01, -60],
|
|
["Mexico/General", 2017, 04, 02, 02, 60],
|
|
["Mexico/General", 2017, 10, 29, 02, -60],
|
|
];
|
|
|
|
void runTests() {
|
|
// Makes sure we don't go into the wrong direction during a
|
|
// daylight-savings change (as happened in #30550).
|
|
for (var test in daylightSavingChanges) {
|
|
for (int i = 0; i < 2; i++) {
|
|
var year = test[1] as int;
|
|
var month = test[2] as int;
|
|
var day = test[3] as int;
|
|
var hour = test[4] as int;
|
|
|
|
var minute = i == 0 ? 0 : test[5] as int;
|
|
// Rather adjust the hours than keeping the minutes.
|
|
hour += minute ~/ 60;
|
|
minute = minute.remainder(60) as int;
|
|
if (hour < 0) {
|
|
hour += 24;
|
|
day--;
|
|
}
|
|
|
|
{
|
|
// Check that microseconds are taken into account.
|
|
var dtMillisecond = new DateTime(year, month, day, hour, minute, 0, 1);
|
|
var dtSecond = new DateTime(year, month, day, hour, minute, 1);
|
|
Expect.equals(const Duration(milliseconds: 999),
|
|
dtSecond.difference(dtMillisecond));
|
|
|
|
dtMillisecond = new DateTime(year, month, day, hour, minute, 0, -1);
|
|
dtSecond = new DateTime(year, month, day, hour, minute, -1);
|
|
Expect.equals(const Duration(milliseconds: 999),
|
|
dtMillisecond.difference(dtSecond));
|
|
}
|
|
|
|
var dt1 = new DateTime(year, month, day, hour);
|
|
var dt2 = new DateTime(year, month, day, hour, 1);
|
|
|
|
// Earlier:
|
|
int earlierDay = day;
|
|
int earlierHour = hour - 1;
|
|
if (earlierHour < 0) {
|
|
earlierHour = 23;
|
|
earlierDay--;
|
|
}
|
|
var dt3 = new DateTime(year, month, earlierDay, earlierHour, 59);
|
|
|
|
var diff1 = dt2.difference(dt1).inMinutes;
|
|
var diff2 = dt1.difference(dt3).inMinutes;
|
|
|
|
if (diff1 == 1 && diff2 == 1 && dt1.hour == hour && dt1.minute == 0) {
|
|
// Regular date-time.
|
|
continue;
|
|
}
|
|
|
|
// At most one is at a distance of more than a minute.
|
|
Expect.isTrue(diff1 == 1 || diff2 == 1);
|
|
|
|
if (diff2 < 0) {
|
|
// This happens, when we ask for invalid times.
|
|
// Suppose daylight-saving is at 2:00 and switches to 3:00. If we
|
|
// ask for 2:59, we get 3:59 (59 minutes after 2:00).
|
|
Expect.isFalse(dt3.day == earlierDay && dt3.hour == earlierHour);
|
|
// If that's the case, then removing one minute from dt1 should
|
|
// not yield a date-time with the earlier values, and it should
|
|
// be far away from dt3.
|
|
var dt4 = dt1.add(const Duration(minutes: -1));
|
|
Expect.isFalse(dt4.day == earlierDay && dt4.hour == earlierHour);
|
|
Expect.isTrue(dt4.isBefore(dt1));
|
|
Expect.isTrue(dt4.day < earlierDay ||
|
|
(dt4.day == earlierDay && dt4.hour < earlierHour));
|
|
continue;
|
|
}
|
|
|
|
// They must be in the right order.
|
|
Expect.isTrue(dt1.isBefore(dt2));
|
|
Expect.isTrue(dt3.isBefore(dt1));
|
|
}
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
// The following code constructs a String with all timezones that are
|
|
// relevant for this test.
|
|
// This can be helpful for running tests in multiple timezones.
|
|
// Typically, one would write something like:
|
|
// for tz in <contents_of_string>; do TZ=$tz tools/test.py ...; done
|
|
var result = new StringBuffer();
|
|
for (int i = 0; i < daylightSavingChanges.length; i += 2) {
|
|
if (i != 0) result.write(" ");
|
|
result.write(daylightSavingChanges[i][0]);
|
|
}
|
|
|
|
runTests();
|
|
}
|