blob: ddbed65725c8bc1a4e842fb740c5e84d7c1c30bb [file] [edit]
@TestOn('vm')
library;
import 'package:test/test.dart';
import 'package:timezone/data/latest.dart';
import 'package:timezone/timezone.dart';
Future<void> main() async {
initializeTimeZones();
final detroit = getLocation('America/Detroit');
final la = getLocation('America/Los_Angeles');
final newYork = getLocation('America/New_York');
group('Constructors', () {
test('Default', () {
final t = TZDateTime(la, 2010, 1, 2, 3, 4, 5, 6, 7);
expect(t.toString(), equals('2010-01-02 03:04:05.006007-0800'));
});
test('Default, only year argument', () {
final t = TZDateTime(la, 2010);
expect(t.toString(), equals('2010-01-01 00:00:00.000-0800'));
});
test('from DateTime', () {
final utcTime = DateTime.utc(2010, 1, 2, 3, 4, 5, 6, 7);
final t = TZDateTime.from(utcTime, newYork);
expect(t.toString(), equals('2010-01-01 22:04:05.006007-0500'));
});
test('from local DateTime', () {
final localTime = DateTime(2010, 1, 2, 3, 4, 5, 6);
final newYorkTime = TZDateTime.from(localTime, newYork);
// New York time should be 5 hours behind UTC.
expect(
newYorkTime.hour,
equals(localTime.toUtc().subtract(const Duration(hours: 5)).hour),
);
});
test('from TZDateTime', () {
final laTime = TZDateTime(la, 2010, 1, 2, 3, 4, 5, 6, 7);
final t = TZDateTime.from(laTime, newYork);
expect(t.toString(), equals('2010-01-02 06:04:05.006007-0500'));
});
test('fromMilliseconds', () {
final t = TZDateTime.fromMillisecondsSinceEpoch(newYork, 1262430245006);
expect(t.toString(), equals('2010-01-02 06:04:05.006-0500'));
});
test('fromMicroseconds', () {
final t = TZDateTime.fromMicrosecondsSinceEpoch(
newYork,
1262430245006007,
);
expect(t.toString(), equals('2010-01-02 06:04:05.006007-0500'));
});
test('utc', () {
final t = TZDateTime.utc(2010, 1, 2, 3, 4, 5, 6, 7);
expect(t.toString(), equals('2010-01-02 03:04:05.006007Z'));
});
});
group('Offsets', () {
group('UTC to America/Detroit', () {
group('Simple translations', () {
final u1 = DateTime.utc(1975, 1, 1, 5);
final x1 = TZDateTime.from(u1, detroit);
test('$u1 => 1975-01-01 00:00:00.000-0500', () {
expect(x1.toString(), equals('1975-01-01 00:00:00.000-0500'));
});
final u2 = u1.subtract(const Duration(milliseconds: 1));
final x2 = TZDateTime.from(u2, detroit);
test('$u2 => 1974-12-31 23:59:59.999-0500', () {
expect(x2.toString(), equals('1974-12-31 23:59:59.999-0500'));
});
final u3 = u1.add(const Duration(milliseconds: 1));
final x3 = TZDateTime.from(u3, detroit);
test('$u3 => 1975-01-01 00:00:00.001-0500', () {
expect(x3.toString(), equals('1975-01-01 00:00:00.001-0500'));
});
});
group('EWT/EPT boundaries', () {
final u1 = DateTime.utc(1945, 09, 30, 6);
final x1 = TZDateTime.from(u1, detroit);
test('$u1 => 1945-09-30 01:00:00.000-0500', () {
expect(x1.toString(), '1945-09-30 01:00:00.000-0500');
});
final u2 = u1.subtract(const Duration(milliseconds: 1));
final x2 = TZDateTime.from(u2, detroit);
test('$u2 => 1945-09-30 01:59:59.999-0400', () {
expect(x2.toString(), equals('1945-09-30 01:59:59.999-0400'));
});
final u3 = u1.add(const Duration(milliseconds: 1));
final x3 = TZDateTime.from(u3, detroit);
test('$u3 => 1945-09-30 01:00:00.001-0500', () {
expect(x3.toString(), equals('1945-09-30 01:00:00.001-0500'));
});
});
});
group('America/Detroit to UTC', () {
group('EWT/EPT boundaries', () {
final x1 = TZDateTime(detroit, 1945, 9, 30, 1);
final u1 = DateTime.fromMillisecondsSinceEpoch(
x1.millisecondsSinceEpoch,
isUtc: true,
);
test('$x1 => 1945-09-30 05:00:00.000Z', () {
expect(u1.toString(), '1945-09-30 05:00:00.000Z');
});
final x2 = x1.subtract(const Duration(milliseconds: 1));
final u2 = DateTime.fromMillisecondsSinceEpoch(
x2.millisecondsSinceEpoch,
isUtc: true,
);
test('$x2 => 1945-09-30 04:59:59.999Z', () {
expect(u2.toString(), equals('1945-09-30 04:59:59.999Z'));
});
final x3 = x1.add(const Duration(milliseconds: 1));
final u3 = DateTime.fromMillisecondsSinceEpoch(
x3.millisecondsSinceEpoch,
isUtc: true,
);
test('$x3 => 1945-09-30 05:00:00.001Z', () {
expect(u3.toString(), equals('1945-09-30 05:00:00.001Z'));
});
final x4 = x1.add(const Duration(hours: 1));
final u4 = DateTime.fromMillisecondsSinceEpoch(
x4.millisecondsSinceEpoch,
isUtc: true,
);
test('$x4 => 1945-09-30 06:00:00.000Z', () {
expect(u4.toString(), equals('1945-09-30 06:00:00.000Z'));
});
final x5 = x2.add(const Duration(hours: 1));
final u5 = DateTime.fromMillisecondsSinceEpoch(
x5.millisecondsSinceEpoch,
isUtc: true,
);
test('$x5 => 1945-09-30 05:59:59.999Z', () {
expect(u5.toString(), equals('1945-09-30 05:59:59.999Z'));
});
});
});
group('America/Detroit DST (negative offset)', () {
// https://www.timeanddate.com/time/change/usa/detroit?year=2023
group('EST/EDT transition', () {
test('2 months before transition', () {
final datetime = TZDateTime(detroit, 2023, 1, 12, 4);
expect(datetime.toString(), '2023-01-12 04:00:00.000-0500');
});
test('1 hour before transition', () {
final datetime = TZDateTime(detroit, 2023, 3, 12, 1);
expect(datetime.toString(), '2023-03-12 01:00:00.000-0500');
});
test('lower transition', () {
final datetime = TZDateTime(detroit, 2023, 3, 12, 2);
expect(datetime.toString(), '2023-03-12 03:00:00.000-0400');
});
test('upper transition', () {
final datetime = TZDateTime(detroit, 2023, 3, 12, 3);
expect(datetime.toString(), '2023-03-12 03:00:00.000-0400');
});
test('1 hour after transition', () {
final datetime = TZDateTime(detroit, 2023, 3, 12, 4);
expect(datetime.toString(), '2023-03-12 04:00:00.000-0400');
});
test('2 months after transition', () {
final datetime = TZDateTime(detroit, 2023, 5, 12, 4);
expect(datetime.toString(), '2023-05-12 04:00:00.000-0400');
});
});
group('EDT/EST transition', () {
test('2 months before transition', () {
final datetime = TZDateTime(detroit, 2023, 9, 5, 1);
expect(datetime.toString(), '2023-09-05 01:00:00.000-0400');
});
test('1 hour before transition', () {
final datetime = TZDateTime(detroit, 2023, 11, 5);
expect(datetime.toString(), '2023-11-05 00:00:00.000-0400');
});
test('lower transition', () {
final datetime = TZDateTime(detroit, 2023, 11, 5, 1);
expect(datetime.toString(), '2023-11-05 01:00:00.000-0400');
});
test('upper transition', () {
final datetime = TZDateTime(detroit, 2023, 11, 5, 2);
expect(datetime.toString(), '2023-11-05 02:00:00.000-0500');
});
test('1 hour after transition', () {
final datetime = TZDateTime(detroit, 2023, 11, 5, 3);
expect(datetime.toString(), '2023-11-05 03:00:00.000-0500');
});
test('2 months after transition', () {
final datetime = TZDateTime(detroit, 2024, 1, 5, 2);
expect(datetime.toString(), '2024-01-05 02:00:00.000-0500');
});
});
});
group('Europe/Berlin DST (positive offset)', () {
// https://www.timeanddate.com/time/change/germany/berlin?year=2023
final berlin = getLocation('Europe/Berlin');
group('EST/EDT transition', () {
test('2 months before transition', () {
final datetime = TZDateTime(berlin, 2023, 1, 26, 2);
expect(datetime.toString(), '2023-01-26 02:00:00.000+0100');
});
test('1 hour before transition', () {
final datetime = TZDateTime(berlin, 2023, 3, 26, 1);
expect(datetime.toString(), '2023-03-26 01:00:00.000+0100');
});
test('lower transition', () {
final datetime = TZDateTime(berlin, 2023, 3, 26, 2);
expect(datetime.toString(), '2023-03-26 03:00:00.000+0200');
});
test('upper transition', () {
final datetime = TZDateTime(berlin, 2023, 3, 26, 3);
expect(datetime.toString(), '2023-03-26 03:00:00.000+0200');
});
test('1 hour after transition', () {
final datetime = TZDateTime(berlin, 2023, 3, 26, 4);
expect(datetime.toString(), '2023-03-26 04:00:00.000+0200');
});
test('2 months after transition', () {
final datetime = TZDateTime(berlin, 2023, 5, 26, 3);
expect(datetime.toString(), '2023-05-26 03:00:00.000+0200');
});
});
group('EDT/EST transition', () {
test('2 months before transition', () {
final datetime = TZDateTime(berlin, 2023, 8, 29, 2);
expect(datetime.toString(), '2023-08-29 02:00:00.000+0200');
});
test('1 hour before transition', () {
final datetime = TZDateTime(berlin, 2023, 10, 29, 1);
expect(datetime.toString(), '2023-10-29 01:00:00.000+0200');
});
test('lower transition', () {
final datetime = TZDateTime(berlin, 2023, 10, 29, 2);
expect(datetime.toString(), '2023-10-29 02:00:00.000+0100');
});
test('upper transition', () {
final datetime = TZDateTime(berlin, 2023, 10, 29, 3);
expect(datetime.toString(), '2023-10-29 03:00:00.000+0100');
});
test('1 hour after transition', () {
final datetime = TZDateTime(berlin, 2023, 10, 29, 4);
expect(datetime.toString(), '2023-10-29 04:00:00.000+0100');
});
test('2 months after transition', () {
final datetime = TZDateTime(berlin, 2024, 1, 29, 3);
expect(datetime.toString(), '2024-01-29 03:00:00.000+0100');
});
});
});
});
group('Timezones', () {
test('getLocation throws $LocationNotFoundException for unrecognized '
'timezone', () {
expect(
() => getLocation('non-existent-location'),
throwsA(const TypeMatcher<LocationNotFoundException>()),
);
});
});
}