forked from srawlins/timezone
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzone_tab.dart
70 lines (57 loc) · 2.46 KB
/
zone_tab.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Copyright (c) 2014, the timezone 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.
/// zone1970.tab file parser
library timezone.src.tzdata.zone_tab;
/// Latitude and longitude of the zone's principal location
/// in ISO 6709 sign-degrees-minutes-seconds format,
/// either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
/// first latitude (+ is north), then longitude (+ is east).
final _geoLocationRe =
RegExp(r'^([+\-])(\d{2,3})(\d{2})(\d{2})?([+\-])(\d{2,3})(\d{2})(\d{2})?$');
class LocationDescription {
final String name;
final List<String> countryCodes;
final double latitude;
final double longitude;
final String comments;
LocationDescription(this.name, this.countryCodes, this.latitude,
this.longitude, this.comments);
factory LocationDescription.fromString(String line) {
final parts = line.split('\t');
final countryCodes = parts[0].split(',');
final name = parts[2];
final comments = parts.length > 3 ? parts[3] : '';
final match = _geoLocationRe.firstMatch(parts[1])!;
final latSign = match.group(1) == '+' ? 1 : -1;
final latDeg = int.parse(match.group(2)!);
final latMinutes = int.parse(match.group(3)!);
final latSecondsRaw = match.group(4);
final latSeconds = latSecondsRaw != null ? int.parse(latSecondsRaw) : 0;
final longSign = match.group(5) == '+' ? 1 : -1;
final longDeg = int.parse(match.group(6)!);
final longMinutes = int.parse(match.group(7)!);
final longSecondsRaw = match.group(8);
final longSeconds = longSecondsRaw != null ? int.parse(longSecondsRaw) : 0;
final latitude = latSign * (latDeg + (latMinutes + (latSeconds / 60)) / 60);
final longitude =
longSign * (longDeg + (longMinutes + (longSeconds / 60)) / 60);
return LocationDescription(
name, countryCodes, latitude, longitude, comments);
}
}
class LocationDescriptionDatabase {
final List<LocationDescription> locations;
LocationDescriptionDatabase(this.locations);
factory LocationDescriptionDatabase.fromString(String data) {
final lines = data.replaceAll('\r\n', '\n').split('\n');
final locations = <LocationDescription>[];
for (final line in lines) {
if (line.isEmpty || line[0].startsWith('#')) {
continue;
}
locations.add(LocationDescription.fromString(line));
}
return LocationDescriptionDatabase(locations);
}
}