blob: 2c87d0fb9d42643bfd7290a9f5d54dba04fe8968 [file] [log] [blame]
// 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;
/// 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);
}
}