Skip to content

Commit 47bc392

Browse files
refactor: move timezone compatibility logic to a new file
1 parent e379b89 commit 47bc392

File tree

2 files changed

+66
-49
lines changed

2 files changed

+66
-49
lines changed

gen/main.dart

Lines changed: 16 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,29 @@ import 'dart:convert' as convert;
22
import 'dart:io';
33

44
import 'package:http/http.dart' as http;
5-
import 'package:timezone/data/latest.dart' as tz;
6-
import 'package:timezone/timezone.dart' as tz;
75

8-
const String _version = '2024a';
6+
import 'timezone_compatibility.dart';
7+
8+
const String TIMEZONE_DATABASE_VERSION = '2024a';
99

1010
void main() async {
11-
final timezones = await loadTimezones(_version);
11+
final timezones = await loadTimezonesWithCountryCodes(
12+
TIMEZONE_DATABASE_VERSION,
13+
);
1214
if (timezones.isEmpty) return;
1315

1416
generateSourceFile('timezone_to_country.g.dart', '_map', timezones);
1517

16-
final unsupported = unsupportedTimezones(timezones);
17-
if (timezones.isEmpty) return;
18+
final unsupported = findUnmappedTimezonesWithCountryCodes(timezones);
19+
if (unsupported.isEmpty) return;
1820

1921
generateSourceFile('timezone_to_country.manual.g.dart', '_map2', unsupported);
2022
}
2123

22-
/// load timezones and parse
23-
Future<Map<String, String>> loadTimezones(String version) async {
24+
/// load timezones with their country code from tz database
25+
Future<Map<String, String>> loadTimezonesWithCountryCodes(
26+
String version,
27+
) async {
2428
/// download the timezone file
2529
final url = Uri.parse(
2630
'https://raw.githubusercontent.com/eggert/tz/$version/zone.tab');
@@ -40,48 +44,11 @@ Future<Map<String, String>> loadTimezones(String version) async {
4044
return map;
4145
}
4246

43-
/// finds unsupported timezones from timezone package
44-
/// and guess their country code
45-
Map<String, String> unsupportedTimezones(Map<String, String> timezones) {
46-
String? guess(String timezoneId) {
47-
if (timezoneId == 'GMT' || timezoneId == 'UTC') return null;
48-
if (timezoneId.startsWith('US/')) return 'US';
49-
if (timezoneId.startsWith('Canada/')) return 'CA';
50-
if (timezoneId.startsWith('Australia/')) return 'AU';
51-
52-
final code = {
53-
'America/Godthab': 'GL',
54-
'America/Montreal': 'CA',
55-
'America/Nipigon': 'CA',
56-
'America/Pangnirtung': 'CA',
57-
'America/Rainy_River': 'CA',
58-
'America/Santa_Isabel': 'MX',
59-
'America/Thunder_Bay': 'CA',
60-
'America/Yellowknife': 'CA',
61-
'Asia/Rangoon': 'MM',
62-
'Europe/Uzhgorod': 'UA',
63-
'Europe/Zaporozhye': 'UA',
64-
'Pacific/Enderbury': 'KI',
65-
'Pacific/Johnston': 'US',
66-
}[timezoneId];
67-
68-
assert(code != null, 'You should implement: $timezoneId.');
69-
return code;
70-
}
71-
72-
tz.initializeTimeZones();
73-
final unsupported = Map.fromEntries(() sync* {
74-
for (final timezoneId in tz.timeZoneDatabase.locations.keys
75-
.where((timezoneId) => timezones[timezoneId] == null)) {
76-
final code = guess(timezoneId);
77-
if (code != null) yield MapEntry(timezoneId, code);
78-
}
79-
}());
80-
return unsupported;
81-
}
82-
8347
Future<void> generateSourceFile(
84-
String fileName, String mapName, Map<String, String> timezones) async {
48+
String fileName,
49+
String mapName,
50+
Map<String, String> timezones,
51+
) async {
8552
/// write to source file
8653
final sb = StringBuffer();
8754
sb.writeln("part of 'timezone_to_country.dart';");

gen/timezone_compatibility.dart

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import 'package:timezone/data/latest.dart' as tz;
2+
import 'package:timezone/timezone.dart' as tz;
3+
4+
/// Find timezones that exist in `timezone` package but not in the tz database,
5+
/// and return their guessed country codes
6+
Map<String, String> findUnmappedTimezonesWithCountryCodes(
7+
Map<String, String> timezones,
8+
) {
9+
tz.initializeTimeZones();
10+
11+
final unmapped = Map.fromEntries(() sync* {
12+
// iterate through timezones that exist in timezone package but not in the tz database
13+
for (final timezoneId in tz.timeZoneDatabase.locations.keys
14+
.where((timezoneId) => timezones[timezoneId] == null)) {
15+
// manually guess the country code for those timezones
16+
final code = _guessCountryCodeFrom(timezoneId);
17+
if (code != null) yield MapEntry(timezoneId, code);
18+
}
19+
}());
20+
21+
return unmapped;
22+
}
23+
24+
String? _guessCountryCodeFrom(String timezoneId) {
25+
if (timezoneId == 'GMT' || timezoneId == 'UTC') return null;
26+
if (timezoneId.startsWith('US/')) return 'US';
27+
if (timezoneId.startsWith('Canada/')) return 'CA';
28+
if (timezoneId.startsWith('Australia/')) return 'AU';
29+
30+
final code = {
31+
'America/Godthab': 'GL',
32+
'America/Montreal': 'CA',
33+
'America/Nipigon': 'CA',
34+
'America/Pangnirtung': 'CA',
35+
'America/Rainy_River': 'CA',
36+
'America/Santa_Isabel': 'MX',
37+
'America/Thunder_Bay': 'CA',
38+
'America/Yellowknife': 'CA',
39+
'Asia/Rangoon': 'MM',
40+
'Europe/Uzhgorod': 'UA',
41+
'Europe/Zaporozhye': 'UA',
42+
'Pacific/Enderbury': 'KI',
43+
'Pacific/Johnston': 'US',
44+
}[timezoneId];
45+
46+
if (code == null) _warn('You should implement: $timezoneId.');
47+
return code;
48+
}
49+
50+
void _warn(String message) => print('\x1B[33m$message\x1B[0m');

0 commit comments

Comments
 (0)