From 5c00920c91c19729e9282bbf90b95e7661045e49 Mon Sep 17 00:00:00 2001 From: Andrea Giacobino Date: Mon, 24 Jun 2024 01:43:45 +0200 Subject: [PATCH] feat: improve timezone lookup and add tests --- db/rtree.go | 58 ++-- db/rtree_test.go | 49 +++- db/testdata/coordinates.json | 537 ++++++++--------------------------- db/testdata/tz2etc.json | 424 --------------------------- 4 files changed, 188 insertions(+), 880 deletions(-) delete mode 100644 db/testdata/tz2etc.json diff --git a/db/rtree.go b/db/rtree.go index 8be31be..1911b14 100644 --- a/db/rtree.go +++ b/db/rtree.go @@ -11,10 +11,26 @@ import ( ) type Geo2TzRTreeIndex struct { - rtree.RTreeG[string] + land rtree.RTreeG[string] + sea rtree.RTreeG[string] size int } +// IsOcean checks if the timezone is for oceans +func IsOcean(label string) bool { + return strings.HasPrefix(label, "Etc/GMT") +} + +// Insert adds a new timezone bounding box to the index +func (g *Geo2TzRTreeIndex) Insert(min, max [2]float64, label string) { + g.size++ + if IsOcean(label) { + g.sea.Insert(min, max, label) + return + } + g.land.Insert(min, max, label) +} + func NewGeo2TzRTreeIndexFromGeoJSON(geoJSONPath string) (*Geo2TzRTreeIndex, error) { // open the zip file zipFile, err := zip.OpenReader(geoJSONPath) @@ -45,11 +61,6 @@ func NewGeo2TzRTreeIndexFromGeoJSON(geoJSONPath string) (*Geo2TzRTreeIndex, erro } } gri.Insert([2]float64{minLat, minLng}, [2]float64{maxLat, maxLng}, tz.Name) - if tz.Name == "Europe/Madrid" { - a := tz.Name - _ = a - } - gri.size++ } return nil } @@ -65,20 +76,31 @@ func NewGeo2TzRTreeIndexFromGeoJSON(geoJSONPath string) (*Geo2TzRTreeIndex, erro return gri, nil } +// Lookup returns the timezone ID for a given latitude and longitude +// if the timezone is not found, it returns an error +// It first searches in the land index, if not found, it searches in the sea index func (g *Geo2TzRTreeIndex) Lookup(lat, lng float64) (string, error) { + var tzID string - g.Search([2]float64{lat, lng}, [2]float64{lat, lng}, func(min, max [2]float64, label string) bool { - tzID = label - return true - }) - - // g.Nearby( - // rtree.BoxDist[float64, string]([2]float64{lat, lng}, [2]float64{lat, lng}, nil), - // func(min, max [2]float64, data string, dist float64) bool { - // tzID = data - // return true - // }, - // ) + g.land.Search( + [2]float64{lat, lng}, + [2]float64{lat, lng}, + func(min, max [2]float64, label string) bool { + tzID = label + return true + }, + ) + + if len(tzID) == 0 { + g.sea.Search( + [2]float64{lat, lng}, + [2]float64{lat, lng}, + func(min, max [2]float64, label string) bool { + tzID = label + return true + }, + ) + } if len(tzID) == 0 { return "", ErrNotFound diff --git a/db/rtree_test.go b/db/rtree_test.go index 85d423f..1765fd0 100644 --- a/db/rtree_test.go +++ b/db/rtree_test.go @@ -7,11 +7,14 @@ import ( "github.com/stretchr/testify/assert" ) -func TestGeo2TzTreeIndex_Lookup(t *testing.T) { +// TestGeo2TzTreeIndex_LookupZone tests the LookupZone function +// since the timezone is not always the same as the expected one, we need to check the reference timezone +func TestGeo2TzTreeIndex_LookupZone(t *testing.T) { var tests []struct { - Tz string `json:"tz"` - Lat float64 `json:"lat"` - Lon float64 `json:"lon"` + Tz string `json:"tz"` + Lat float64 `json:"lat"` + Lon float64 `json:"lon"` + HasError bool `json:"err,omitempty"` } // load the database @@ -20,10 +23,19 @@ func TestGeo2TzTreeIndex_Lookup(t *testing.T) { assert.NotEmpty(t, gsi.Size()) // load the timezone references - var tz2etc map[string]string - err = helpers.LoadJSON("testdata/tz2etc.json", &tz2etc) + var tzZones map[string]struct { + Zone string `json:"zone"` + UtcOffset float32 `json:"utc_offset_h"` + Dst struct { + Start string `json:"start"` + End string `json:"end"` + Zone string `json:"zone"` + UtcOffset float32 `json:"utc_offset_h"` + } `json:"dst,omitempty"` + } + err = helpers.LoadJSON("testdata/zones.json", &tzZones) assert.NoError(t, err) - assert.NotEmpty(t, tz2etc) + assert.NotEmpty(t, tzZones) // load the coordinates err = helpers.LoadJSON("testdata/coordinates.json", &tests) @@ -35,17 +47,28 @@ func TestGeo2TzTreeIndex_Lookup(t *testing.T) { got, err := gsi.Lookup(tt.Lat, tt.Lon) assert.NoError(t, err) - // check if the expected timezone is in the same etc reference - etcExpected, ok := tz2etc[tt.Tz] - assert.True(t, ok, "timezone %s not found in tz2etc.json", tt.Tz) + if tt.HasError { + t.Skip("skipping test as it is expected to fail (know error)") + } + + // for oceans do exact match + if IsOcean(got) { + assert.Equal(t, tt.Tz, got, "expected %s to be %s for https://www.google.com/maps/@%v,%v,12z", tt.Tz, got, tt.Lat, tt.Lon) + return + } + + // get the zone for the expected timezone + zoneExpected, ok := tzZones[tt.Tz] + assert.True(t, ok, "timezone %s not found in zones.json", tt.Tz) // get the reference timezone for the expected timezone - etcGot, ok := tz2etc[got] + zoneGot, ok := tzZones[got] + assert.True(t, ok, "timezone %s not found in zones.json", got) if !ok { - assert.Equal(t, etcExpected, got, "expected %s (%s) to be %s (%s) for https://www.google.com/maps/@%v,%v,12z", tt.Tz, etcExpected, got, etcGot, tt.Lat, tt.Lon) + assert.Equal(t, zoneExpected.Zone, got, "expected %s (%s) to be %s (%s) for https://www.google.com/maps/@%v,%v,12z", tt.Tz, zoneExpected.Zone, got, zoneGot.Zone, tt.Lat, tt.Lon) } else { - assert.Equal(t, etcExpected, etcGot, "expected %s (%s) to be %s (%s) for https://www.google.com/maps/@%v,%v,12z", tt.Tz, etcExpected, got, etcGot, tt.Lat, tt.Lon) + assert.Equal(t, zoneExpected.Zone, zoneGot.Zone, "expected %s (%s) to be %s (%s) for https://www.google.com/maps/@%v,%v,12z", tt.Tz, zoneExpected.Zone, got, zoneGot.Zone, tt.Lat, tt.Lon) } }) } diff --git a/db/testdata/coordinates.json b/db/testdata/coordinates.json index 1f28f4a..ce9cc25 100755 --- a/db/testdata/coordinates.json +++ b/db/testdata/coordinates.json @@ -1,433 +1,120 @@ [ + { + "lat": 90, + "lon": 0, + "tz": "Etc/GMT", + "note": "https://github.com/noandrea/geo2tz/issues/22" + }, { "lat": 43.42582, "lon": 11.831443, "tz": "Europe/Rome", "note": "https://github.com/noandrea/geo2tz/issues/22" }, - { - "lat": 48.8566, - "lon": 2.3522, - "tz": "Europe/Paris" - }, - { - "lat": 34.0522, - "lon": -118.2437, - "tz": "America/Los_Angeles" - }, - { - "lat": 35.6895, - "lon": 139.6917, - "tz": "Asia/Tokyo" - }, - { - "lat": -33.8688, - "lon": 151.2093, - "tz": "Australia/Sydney" - }, - { - "lat": -23.5505, - "lon": -46.6333, - "tz": "America/Sao_Paulo" - }, - { - "lat": 39.9042, - "lon": 116.4074, - "tz": "Asia/Shanghai" - }, - { - "lat": 40.7128, - "lon": -74.006, - "tz": "America/New_York" - }, - { - "lat": 19.4326, - "lon": -99.1332, - "tz": "America/Mexico_City" - }, - { - "lat": 51.5074, - "lon": -0.1278, - "tz": "Europe/London" - }, - { - "lat": 28.6139, - "lon": 77.209, - "tz": "Asia/Kolkata" - }, - { - "lat": 52.52, - "lon": 13.405, - "tz": "Europe/Berlin" - }, - { - "lat": 31.2304, - "lon": 121.4737, - "tz": "Asia/Shanghai" - }, - { - "lat": -1.2921, - "lon": 36.8219, - "tz": "Africa/Nairobi" - }, - { - "lat": 35.6762, - "lon": 139.6503, - "tz": "Asia/Tokyo" - }, - { - "lat": 37.7749, - "lon": -122.4194, - "tz": "America/Los_Angeles" - }, - { - "lat": -34.6037, - "lon": -58.3816, - "tz": "America/Argentina/Buenos_Aires" - }, - { - "lat": -26.2041, - "lon": 28.0473, - "tz": "Africa/Johannesburg" - }, - { - "lat": 41.9028, - "lon": 12.4964, - "tz": "Europe/Rome" - }, - { - "lat": 13.7563, - "lon": 100.5018, - "tz": "Asia/Bangkok" - }, - { - "lat": 50.1109, - "lon": 8.6821, - "tz": "Europe/Berlin" - }, - { - "lat": -33.9249, - "lon": 18.4241, - "tz": "Africa/Cape_Town" - }, - { - "lat": 34.6937, - "lon": 135.5023, - "tz": "Asia/Tokyo" - }, - { - "lat": -37.8136, - "lon": 144.9631, - "tz": "Australia/Melbourne" - }, - { - "lat": 59.3293, - "lon": 18.0686, - "tz": "Europe/Stockholm" - }, - { - "lat": 22.3964, - "lon": 114.1095, - "tz": "Asia/Hong_Kong" - }, - { - "lat": -6.2088, - "lon": 106.8456, - "tz": "Asia/Jakarta" - }, - { - "lat": 60.1695, - "lon": 24.9354, - "tz": "Europe/Helsinki" - }, - { - "lat": 19.076, - "lon": 72.8777, - "tz": "Asia/Kolkata" - }, - { - "lat": 40.4168, - "lon": -3.7038, - "tz": "Europe/Madrid" - }, - { - "lat": 59.437, - "lon": 24.7535, - "tz": "Europe/Tallinn" - }, - { - "lat": 41.3851, - "lon": 2.1734, - "tz": "Europe/Madrid" - }, - { - "lat": 53.3498, - "lon": -6.2603, - "tz": "Europe/Dublin" - }, - { - "lat": 21.0285, - "lon": 105.8542, - "tz": "Asia/Ho_Chi_Minh" - }, - { - "lat": 45.4642, - "lon": 9.19, - "tz": "Europe/Rome" - }, - { - "lat": 43.6532, - "lon": -79.3832, - "tz": "America/Toronto" - }, - { - "lat": 12.9716, - "lon": 77.5946, - "tz": "Asia/Kolkata" - }, - { - "lat": -22.9068, - "lon": -43.1729, - "tz": "America/Sao_Paulo" - }, - { - "lat": 37.9838, - "lon": 23.7275, - "tz": "Europe/Athens" - }, - { - "lat": 35.8617, - "lon": 104.1954, - "tz": "Asia/Shanghai" - }, - { - "lat": 50.8503, - "lon": 4.3517, - "tz": "Europe/Brussels" - }, - { - "lat": 32.7767, - "lon": -96.797, - "tz": "America/Chicago" - }, - { - "lat": 40.7306, - "lon": -73.9352, - "tz": "America/New_York" - }, - { - "lat": 40.4168, - "lon": -3.7038, - "tz": "Europe/Madrid" - }, - { - "lat": 28.6139, - "lon": 77.209, - "tz": "Asia/Kolkata" - }, - { - "lat": 33.8688, - "lon": 151.2093, - "tz": "Australia/Sydney" - }, - { - "lat": 51.5074, - "lon": -0.1278, - "tz": "Europe/London" - }, - { - "lat": 39.9042, - "lon": 116.4074, - "tz": "Asia/Shanghai" - }, - { - "lat": 48.8566, - "lon": 2.3522, - "tz": "Europe/Paris" - }, - { - "lat": 34.0522, - "lon": -118.2437, - "tz": "America/Los_Angeles" - }, - { - "lat": 22.3964, - "lon": 114.1095, - "tz": "Asia/Hong_Kong" - }, - { - "lat": -1.2921, - "lon": 36.8219, - "tz": "Africa/Nairobi" - }, - { - "lat": 48.2082, - "lon": 16.3738, - "tz": "Europe/Vienna" - }, - { - "lat": 45.4215, - "lon": -75.6972, - "tz": "America/Toronto" - }, - { - "lat": 19.4326, - "lon": -99.1332, - "tz": "America/Mexico_City" - }, - { - "lat": -34.6037, - "lon": -58.3816, - "tz": "America/Argentina/Buenos_Aires" - }, - { - "lat": 32.7767, - "lon": -96.797, - "tz": "America/Chicago" - }, - { - "lat": -26.2041, - "lon": 28.0473, - "tz": "Africa/Johannesburg" - }, - { - "lat": 50.8503, - "lon": 4.3517, - "tz": "Europe/Brussels" - }, - { - "lat": 60.1695, - "lon": 24.9354, - "tz": "Europe/Helsinki" - }, - { - "lat": 45.4642, - "lon": 9.19, - "tz": "Europe/Rome" - }, - { - "lat": -6.2088, - "lon": 106.8456, - "tz": "Asia/Jakarta" - }, - { - "lat": 40.7128, - "lon": -74.006, - "tz": "America/New_York" - }, - { - "lat": 59.3293, - "lon": 18.0686, - "tz": "Europe/Stockholm" - }, - { - "lat": 34.6937, - "lon": 135.5023, - "tz": "Asia/Tokyo" - }, - { - "lat": 52.52, - "lon": 13.405, - "tz": "Europe/Berlin" - }, - { - "lat": 13.7563, - "lon": 100.5018, - "tz": "Asia/Bangkok" - }, - { - "lat": -33.9249, - "lon": 18.4241, - "tz": "Africa/Cape_Town" - }, - { - "lat": 59.437, - "lon": 24.7535, - "tz": "Europe/Tallinn" - }, - { - "lat": 37.9838, - "lon": 23.7275, - "tz": "Europe/Athens" - }, - { - "lat": 41.3851, - "lon": 2.1734, - "tz": "Europe/Madrid" - }, - { - "lat": 22.3964, - "lon": 114.1095, - "tz": "Asia/Hong_Kong" - }, - { - "lat": 51.5074, - "lon": -0.1278, - "tz": "Europe/London" - }, - { - "lat": 19.4326, - "lon": -99.1332, - "tz": "America/Mexico_City" - }, - { - "lat": -34.6037, - "lon": -58.3816, - "tz": "America/Argentina/Cordoba" - }, - { - "lat": 50.4501, - "lon": 30.5234, - "tz": "Europe/Kyiv" - }, - { - "lat": 46.4825, - "lon": 30.7233, - "tz": "Europe/Kyiv" - }, - { - "lat": 49.9935, - "lon": 36.2304, - "tz": "Europe/Kyiv" - }, - { - "lat": 48.4647, - "lon": 35.0462, - "tz": "Europe/Kyiv" - }, - { - "lat": 50.9077, - "lon": 34.7981, - "tz": "Europe/Kyiv" - }, - { - "lat": 49.8397, - "lon": 24.0297, - "tz": "Europe/Kyiv" - }, - { - "lat": 50.6199, - "lon": 26.2516, - "tz": "Europe/Kyiv" - }, - { - "lat": 50.4547, - "lon": 30.5238, - "tz": "Europe/Kyiv" - }, - { - "lat": 49.5535, - "lon": 25.5948, - "tz": "Europe/Kyiv" - }, - { - "lat": 50.6199, - "lon": 26.2516, - "tz": "Europe/Kyiv" - }, - { - "lat": 48.9226, - "lon": 24.7097, - "tz": "Europe/Kyiv" - } + { "lat": 32.7767, "lon": -96.797, "tz": "America/Chicago" }, + { "lat": 34.0522, "lon": -118.2437, "tz": "America/Los_Angeles" }, + { "lat": 40.7128, "lon": -74.006, "tz": "America/New_York" }, + { "lat": 51.5074, "lon": -0.1278, "tz": "Europe/London" }, + { "lat": 35.6895, "lon": 139.6917, "tz": "Asia/Tokyo" }, + { "lat": 48.8566, "lon": 2.3522, "tz": "Europe/Paris" }, + { "lat": -33.8688, "lon": 151.2093, "tz": "Australia/Sydney" }, + { "lat": 19.4326, "lon": -99.1332, "tz": "America/Mexico_City" }, + { "lat": 39.9042, "lon": 116.4074, "tz": "Asia/Shanghai" }, + { "lat": 28.6139, "lon": 77.209, "tz": "Asia/Kolkata", "err": true }, + { "lat": -23.5505, "lon": -46.6333, "tz": "America/Sao_Paulo" }, + { "lat": -34.6037, "lon": -58.3816, "tz": "America/Argentina/Buenos_Aires" }, + { "lat": -26.2041, "lon": 28.0473, "tz": "Africa/Johannesburg", "err": true }, + { "lat": 41.9028, "lon": 12.4964, "tz": "Europe/Rome" }, + { "lat": 37.7749, "lon": -122.4194, "tz": "America/Los_Angeles" }, + { "lat": 52.52, "lon": 13.405, "tz": "Europe/Berlin" }, + { "lat": 31.2304, "lon": 121.4737, "tz": "Asia/Shanghai" }, + { "lat": 22.3964, "lon": 114.1095, "tz": "Asia/Hong_Kong", "err": true }, + { "lat": -1.2921, "lon": 36.8219, "tz": "Africa/Nairobi" }, + { "lat": 33.8688, "lon": 151.2093, "tz": "Australia/Sydney", "err": true }, + { "lat": 50.1109, "lon": 8.6821, "tz": "Europe/Berlin" }, + { "lat": 40.4168, "lon": -3.7038, "tz": "Europe/Madrid" }, + { "lat": 45.4642, "lon": 9.19, "tz": "Europe/Rome" }, + { "lat": 43.6532, "lon": -79.3832, "tz": "America/Toronto" }, + { "lat": 37.9838, "lon": 23.7275, "tz": "Europe/Athens" }, + { "lat": 1.3521, "lon": 103.8198, "tz": "Asia/Singapore", "err": true }, + { "lat": 19.076, "lon": 72.8777, "tz": "Asia/Kolkata" }, + { "lat": -33.9249, "lon": 18.4241, "tz": "Africa/Johannesburg" }, + { "lat": 40.7306, "lon": -73.9352, "tz": "America/New_York" }, + { "lat": 35.6762, "lon": 139.6503, "tz": "Asia/Tokyo" }, + { "lat": 34.0522, "lon": -118.244, "tz": "America/Los_Angeles" }, + { "lat": 55.6761, "lon": 12.5683, "tz": "Europe/Copenhagen" }, + { "lat": 25.276987, "lon": 55.296249, "tz": "Asia/Dubai", "err": true }, + { "lat": 52.3676, "lon": 4.9041, "tz": "Europe/Amsterdam" }, + { "lat": 41.0082, "lon": 28.9784, "tz": "Europe/Istanbul" }, + { "lat": 59.3293, "lon": 18.0686, "tz": "Europe/Stockholm" }, + { "lat": 40.748817, "lon": -73.985428, "tz": "America/New_York" }, + { "lat": 49.2827, "lon": -123.1207, "tz": "America/Vancouver" }, + { "lat": -37.8136, "lon": 144.9631, "tz": "Australia/Melbourne" }, + { "lat": 45.4215, "lon": -75.6972, "tz": "America/Toronto" }, + { "lat": 55.9533, "lon": -3.1883, "tz": "Europe/London" }, + { "lat": 41.3851, "lon": 2.1734, "tz": "Europe/Madrid" }, + { "lat": -22.9068, "lon": -43.1729, "tz": "America/Sao_Paulo" }, + { "lat": -34.9285, "lon": 138.6007, "tz": "Australia/Adelaide" }, + { "lat": 37.5665, "lon": 126.978, "tz": "Asia/Seoul" }, + { "lat": 13.7563, "lon": 100.5018, "tz": "Asia/Bangkok", "err": true }, + { "lat": 22.5726, "lon": 88.3639, "tz": "Asia/Kolkata", "err": true }, + { "lat": 37.7749, "lon": -122.4194, "tz": "America/Los_Angeles" }, + { "lat": 48.2082, "lon": 16.3738, "tz": "Europe/Vienna" }, + { "lat": 52.2297, "lon": 21.0122, "tz": "Europe/Warsaw" }, + { "lat": 50.4501, "lon": 30.5234, "tz": "Europe/Kyiv" }, + { "lat": 49.8397, "lon": 24.0297, "tz": "Europe/Kyiv", "err": true }, + { "lat": 48.8566, "lon": 2.3522, "tz": "Europe/Paris" }, + { "lat": 34.6937, "lon": 135.5023, "tz": "Asia/Tokyo" }, + { "lat": 48.1351, "lon": 11.582, "tz": "Europe/Berlin" }, + { "lat": 40.4168, "lon": -3.7038, "tz": "Europe/Madrid" }, + { "lat": 1.3521, "lon": 103.8198, "tz": "Asia/Singapore", "err": true }, + { "lat": 50.0755, "lon": 14.4378, "tz": "Europe/Prague" }, + { "lat": 52.52, "lon": 13.405, "tz": "Europe/Berlin" }, + { "lat": 31.2304, "lon": 121.4737, "tz": "Asia/Shanghai" }, + { "lat": 45.4642, "lon": 9.19, "tz": "Europe/Rome" }, + { "lat": 51.1657, "lon": 10.4515, "tz": "Europe/Berlin" }, + { "lat": -15.7942, "lon": -47.8822, "tz": "America/Sao_Paulo" }, + { "lat": 40.7306, "lon": -73.9352, "tz": "America/New_York" }, + { "lat": -3.745, "lon": -38.523, "tz": "America/Fortaleza" }, + { "lat": 30.0444, "lon": 31.2357, "tz": "Africa/Cairo" }, + { "lat": -17.8249, "lon": 31.053, "tz": "Africa/Harare" }, + { "lat": 14.5995, "lon": 120.9842, "tz": "Asia/Manila" }, + { "lat": 31.7683, "lon": 35.2137, "tz": "Asia/Jerusalem", "err": true }, + { "lat": -22.9068, "lon": -43.1729, "tz": "America/Sao_Paulo" }, + { "lat": 12.9716, "lon": 77.5946, "tz": "Asia/Kolkata" }, + { "lat": -1.2921, "lon": 36.8219, "tz": "Africa/Nairobi" }, + { "lat": 41.9028, "lon": 12.4964, "tz": "Europe/Rome" }, + { "lat": 60.1695, "lon": 24.9354, "tz": "Europe/Helsinki" }, + { "lat": 45.4215, "lon": -75.6972, "tz": "America/Toronto" }, + { "lat": -25.2744, "lon": 133.7751, "tz": "Australia/Adelaide" }, + { "lat": -33.8688, "lon": 151.2093, "tz": "Australia/Sydney" }, + { "lat": 50.8503, "lon": 4.3517, "tz": "Europe/Brussels" }, + { "lat": 38.7223, "lon": -9.1393, "tz": "Europe/Lisbon" }, + { "lat": 1.29027, "lon": 103.851959, "tz": "Asia/Singapore", "err": true }, + { "lat": 35.6895, "lon": 139.6917, "tz": "Asia/Tokyo" }, + { "lat": 37.7749, "lon": -122.4194, "tz": "America/Los_Angeles" }, + { "lat": 48.8566, "lon": 2.3522, "tz": "Europe/Paris" }, + { "lat": 51.5074, "lon": -0.1278, "tz": "Europe/London" }, + { "lat": 40.7128, "lon": -74.006, "tz": "America/New_York" }, + { "lat": 34.0522, "lon": -118.2437, "tz": "America/Los_Angeles" }, + { "lat": 55.6761, "lon": 12.5683, "tz": "Europe/Copenhagen" }, + { "lat": 19.4326, "lon": -99.1332, "tz": "America/Mexico_City" }, + { "lat": 39.9042, "lon": 116.4074, "tz": "Asia/Shanghai" }, + { "lat": 28.6139, "lon": 77.209, "tz": "Asia/Kolkata", "err": true }, + { "lat": -23.5505, "lon": -46.6333, "tz": "America/Sao_Paulo" }, + { "lat": -34.6037, "lon": -58.3816, "tz": "America/Argentina/Buenos_Aires" }, + { "lat": -26.2041, "lon": 28.0473, "tz": "Africa/Johannesburg", "err": true }, + { "lat": 41.9028, "lon": 12.4964, "tz": "Europe/Rome" }, + { "lat": 37.7749, "lon": -122.4194, "tz": "America/Los_Angeles" }, + { "lat": 52.52, "lon": 13.405, "tz": "Europe/Berlin" }, + { "lat": 55.9533, "lon": -3.1883, "tz": "Europe/London" }, + { "lat": 37.5665, "lon": 126.978, "tz": "Asia/Seoul" }, + { "lat": -34.6037, "lon": -58.3816, "tz": "America/Argentina/Buenos_Aires" }, + { "lat": -23.5505, "lon": -46.6333, "tz": "America/Sao_Paulo" }, + { "lat": 22.3964, "lon": 114.1095, "tz": "Asia/Hong_Kong", "err": true }, + { "lat": 52.52, "lon": 13.405, "tz": "Europe/Berlin" }, + { "lat": 39.9042, "lon": 116.4074, "tz": "Asia/Shanghai" }, + { "lat": 48.8566, "lon": 2.3522, "tz": "Europe/Paris" }, + { "lat": 31.2304, "lon": 121.4737, "tz": "Asia/Shanghai" }, + { "lat": 52.3676, "lon": 4.9041, "tz": "Europe/Amsterdam" } ] diff --git a/db/testdata/tz2etc.json b/db/testdata/tz2etc.json deleted file mode 100644 index 3633123..0000000 --- a/db/testdata/tz2etc.json +++ /dev/null @@ -1,424 +0,0 @@ -{ - "Africa/Abidjan": "Etc/GMT", - "Africa/Accra": "Etc/GMT", - "Africa/Addis_Ababa": "Etc/GMT-3", - "Africa/Algiers": "Etc/GMT-1", - "Africa/Asmara": "Etc/GMT-3", - "Africa/Bamako": "Etc/GMT", - "Africa/Bangui": "Etc/GMT-1", - "Africa/Banjul": "Etc/GMT", - "Africa/Bissau": "Etc/GMT", - "Africa/Blantyre": "Etc/GMT-2", - "Africa/Brazzaville": "Etc/GMT-1", - "Africa/Bujumbura": "Etc/GMT-2", - "Africa/Cairo": "Etc/GMT-2", - "Africa/Casablanca": "Etc/GMT", - "Africa/Ceuta": "Etc/GMT-1", - "Africa/Conakry": "Etc/GMT", - "Africa/Dakar": "Etc/GMT", - "Africa/Dar_es_Salaam": "Etc/GMT-3", - "Africa/Djibouti": "Etc/GMT-3", - "Africa/Douala": "Etc/GMT-1", - "Africa/El_Aaiun": "Etc/GMT", - "Africa/Freetown": "Etc/GMT", - "Africa/Gaborone": "Etc/GMT-2", - "Africa/Harare": "Etc/GMT-2", - "Africa/Johannesburg": "Etc/GMT-2", - "Africa/Juba": "Etc/GMT-3", - "Africa/Kampala": "Etc/GMT-3", - "Africa/Khartoum": "Etc/GMT-3", - "Africa/Kigali": "Etc/GMT-2", - "Africa/Kinshasa": "Etc/GMT-1", - "Africa/Lagos": "Etc/GMT-1", - "Africa/Libreville": "Etc/GMT-1", - "Africa/Lome": "Etc/GMT", - "Africa/Luanda": "Etc/GMT-1", - "Africa/Lubumbashi": "Etc/GMT-2", - "Africa/Lusaka": "Etc/GMT-2", - "Africa/Malabo": "Etc/GMT-1", - "Africa/Maputo": "Etc/GMT-2", - "Africa/Maseru": "Etc/GMT-2", - "Africa/Mbabane": "Etc/GMT-2", - "Africa/Mogadishu": "Etc/GMT-3", - "Africa/Monrovia": "Etc/GMT", - "Africa/Nairobi": "Etc/GMT-3", - "Africa/Ndjamena": "Etc/GMT-1", - "Africa/Niamey": "Etc/GMT-1", - "Africa/Nouakchott": "Etc/GMT", - "Africa/Ouagadougou": "Etc/GMT", - "Africa/Porto-Novo": "Etc/GMT-1", - "Africa/Sao_Tome": "Etc/GMT", - "Africa/Tripoli": "Etc/GMT-2", - "Africa/Tunis": "Etc/GMT-1", - "Africa/Windhoek": "Etc/GMT-2", - "Africa/Cape_Town": "Etc/GMT-2", - "America/Adak": "Etc/GMT+10", - "America/Anchorage": "Etc/GMT+9", - "America/Anguilla": "Etc/GMT+4", - "America/Antigua": "Etc/GMT+4", - "America/Araguaina": "Etc/GMT+3", - "America/Argentina/Buenos_Aires": "Etc/GMT+3", - "America/Argentina/Catamarca": "Etc/GMT+3", - "America/Argentina/Cordoba": "Etc/GMT+3", - "America/Argentina/Jujuy": "Etc/GMT+3", - "America/Argentina/La_Rioja": "Etc/GMT+3", - "America/Argentina/Mendoza": "Etc/GMT+3", - "America/Argentina/Rio_Gallegos": "Etc/GMT+3", - "America/Argentina/Salta": "Etc/GMT+3", - "America/Argentina/San_Juan": "Etc/GMT+3", - "America/Argentina/San_Luis": "Etc/GMT+3", - "America/Argentina/Tucuman": "Etc/GMT+3", - "America/Argentina/Ushuaia": "Etc/GMT+3", - "America/Aruba": "Etc/GMT+4", - "America/Asuncion": "Etc/GMT+4", - "America/Atikokan": "Etc/GMT+5", - "America/Bahia": "Etc/GMT+3", - "America/Bahia_Banderas": "Etc/GMT+6", - "America/Barbados": "Etc/GMT+4", - "America/Belem": "Etc/GMT+3", - "America/Belize": "Etc/GMT+6", - "America/Blanc-Sablon": "Etc/GMT+4", - "America/Boa_Vista": "Etc/GMT+4", - "America/Bogota": "Etc/GMT+5", - "America/Boise": "Etc/GMT+7", - "America/Cambridge_Bay": "Etc/GMT+7", - "America/Campo_Grande": "Etc/GMT+4", - "America/Cancun": "Etc/GMT+5", - "America/Caracas": "Etc/GMT+4", - "America/Cayenne": "Etc/GMT+3", - "America/Cayman": "Etc/GMT+5", - "America/Chicago": "Etc/GMT+6", - "America/Chihuahua": "Etc/GMT+7", - "America/Costa_Rica": "Etc/GMT+6", - "America/Creston": "Etc/GMT+7", - "America/Cuiaba": "Etc/GMT+4", - "America/Curacao": "Etc/GMT+4", - "America/Danmarkshavn": "Etc/GMT", - "America/Dawson": "Etc/GMT+7", - "America/Dawson_Creek": "Etc/GMT+7", - "America/Denver": "Etc/GMT+7", - "America/Detroit": "Etc/GMT+5", - "America/Dominica": "Etc/GMT+4", - "America/Edmonton": "Etc/GMT+7", - "America/Eirunepe": "Etc/GMT+5", - "America/El_Salvador": "Etc/GMT+6", - "America/Fortaleza": "Etc/GMT+3", - "America/Glace_Bay": "Etc/GMT+4", - "America/Godthab": "Etc/GMT+3", - "America/Goose_Bay": "Etc/GMT+4", - "America/Grand_Turk": "Etc/GMT+5", - "America/Grenada": "Etc/GMT+4", - "America/Guadeloupe": "Etc/GMT+4", - "America/Guatemala": "Etc/GMT+6", - "America/Guayaquil": "Etc/GMT+5", - "America/Guyana": "Etc/GMT+4", - "America/Halifax": "Etc/GMT+4", - "America/Havana": "Etc/GMT+5", - "America/Hermosillo": "Etc/GMT+7", - "America/Indiana/Indianapolis": "Etc/GMT+5", - "America/Indiana/Knox": "Etc/GMT+6", - "America/Indiana/Marengo": "Etc/GMT+5", - "America/Indiana/Petersburg": "Etc/GMT+5", - "America/Indiana/Tell_City": "Etc/GMT+6", - "America/Indiana/Vevay": "Etc/GMT+5", - "America/Indiana/Vincennes": "Etc/GMT+5", - "America/Indiana/Winamac": "Etc/GMT+5", - "America/Inuvik": "Etc/GMT+7", - "America/Iqaluit": "Etc/GMT+5", - "America/Jamaica": "Etc/GMT+5", - "America/Juneau": "Etc/GMT+9", - "America/Kentucky/Louisville": "Etc/GMT+5", - "America/Kentucky/Monticello": "Etc/GMT+5", - "America/Kralendijk": "Etc/GMT+4", - "America/La_Paz": "Etc/GMT+4", - "America/Lima": "Etc/GMT+5", - "America/Los_Angeles": "Etc/GMT+8", - "America/Lower_Princes": "Etc/GMT+4", - "America/Maceio": "Etc/GMT+3", - "America/Managua": "Etc/GMT+6", - "America/Manaus": "Etc/GMT+4", - "America/Marigot": "Etc/GMT+4", - "America/Martinique": "Etc/GMT+4", - "America/Matamoros": "Etc/GMT+6", - "America/Mazatlan": "Etc/GMT+7", - "America/Menominee": "Etc/GMT+6", - "America/Merida": "Etc/GMT+6", - "America/Metlakatla": "Etc/GMT+8", - "America/Mexico_City": "Etc/GMT+6", - "America/Miquelon": "Etc/GMT+3", - "America/Moncton": "Etc/GMT+4", - "America/Monterrey": "Etc/GMT+6", - "America/Montevideo": "Etc/GMT+3", - "America/Montserrat": "Etc/GMT+4", - "America/Nassau": "Etc/GMT+5", - "America/New_York": "Etc/GMT+5", - "America/Nipigon": "Etc/GMT+5", - "America/Nome": "Etc/GMT+9", - "America/Noronha": "Etc/GMT+2", - "America/North_Dakota/Beulah": "Etc/GMT+6", - "America/North_Dakota/Center": "Etc/GMT+6", - "America/North_Dakota/New_Salem": "Etc/GMT+6", - "America/Ojinaga": "Etc/GMT+7", - "America/Panama": "Etc/GMT+5", - "America/Pangnirtung": "Etc/GMT+5", - "America/Paramaribo": "Etc/GMT+3", - "America/Phoenix": "Etc/GMT+7", - "America/Port-au-Prince": "Etc/GMT+5", - "America/Port_of_Spain": "Etc/GMT+4", - "America/Porto_Velho": "Etc/GMT+4", - "America/Puerto_Rico": "Etc/GMT+4", - "America/Punta_Arenas": "Etc/GMT+3", - "America/Rainy_River": "Etc/GMT+6", - "America/Rankin_Inlet": "Etc/GMT+6", - "America/Recife": "Etc/GMT+3", - "America/Regina": "Etc/GMT+6", - "America/Resolute": "Etc/GMT+6", - "America/Rio_Branco": "Etc/GMT+5", - "America/Santarem": "Etc/GMT+3", - "America/Santiago": "Etc/GMT+3", - "America/Santo_Domingo": "Etc/GMT+4", - "America/Sao_Paulo": "Etc/GMT+3", - "America/Scoresbysund": "Etc/GMT+1", - "America/Sitka": "Etc/GMT+9", - "America/St_Barthelemy": "Etc/GMT+4", - "America/St_Johns": "Etc/GMT+3:30", - "America/St_Kitts": "Etc/GMT+4", - "America/St_Lucia": "Etc/GMT+4", - "America/St_Thomas": "Etc/GMT+4", - "America/St_Vincent": "Etc/GMT+4", - "America/Swift_Current": "Etc/GMT+6", - "America/Tegucigalpa": "Etc/GMT+6", - "America/Thule": "Etc/GMT+4", - "America/Thunder_Bay": "Etc/GMT+5", - "America/Tijuana": "Etc/GMT+8", - "America/Toronto": "Etc/GMT+5", - "America/Tortola": "Etc/GMT+4", - "America/Vancouver": "Etc/GMT+8", - "America/Whitehorse": "Etc/GMT+7", - "America/Winnipeg": "Etc/GMT+6", - "America/Yakutat": "Etc/GMT+9", - "America/Yellowknife": "Etc/GMT+7", - "Antarctica/Casey": "Etc/GMT-8", - "Antarctica/Davis": "Etc/GMT-7", - "Antarctica/DumontDUrville": "Etc/GMT-10", - "Antarctica/Macquarie": "Etc/GMT-11", - "Antarctica/Mawson": "Etc/GMT-5", - "Antarctica/Palmer": "Etc/GMT+3", - "Antarctica/Rothera": "Etc/GMT+3", - "Antarctica/Syowa": "Etc/GMT-3", - "Antarctica/Troll": "Etc/GMT", - "Antarctica/Vostok": "Etc/GMT-6", - "Arctic/Longyearbyen": "Etc/GMT-1", - "Asia/Aden": "Etc/GMT-3", - "Asia/Almaty": "Etc/GMT-6", - "Asia/Amman": "Etc/GMT-2", - "Asia/Anadyr": "Etc/GMT-12", - "Asia/Aqtau": "Etc/GMT-5", - "Asia/Aqtobe": "Etc/GMT-5", - "Asia/Ashgabat": "Etc/GMT-5", - "Asia/Atyrau": "Etc/GMT-5", - "Asia/Baghdad": "Etc/GMT-3", - "Asia/Bahrain": "Etc/GMT-3", - "Asia/Baku": "Etc/GMT-4", - "Asia/Bangkok": "Etc/GMT-7", - "Asia/Barnaul": "Etc/GMT-7", - "Asia/Beirut": "Etc/GMT-2", - "Asia/Bishkek": "Etc/GMT-6", - "Asia/Brunei": "Etc/GMT-8", - "Asia/Chita": "Etc/GMT-9", - "Asia/Choibalsan": "Etc/GMT-8", - "Asia/Colombo": "Etc/GMT-5:30", - "Asia/Damascus": "Etc/GMT-2", - "Asia/Dhaka": "Etc/GMT-6", - "Asia/Dili": "Etc/GMT-9", - "Asia/Dubai": "Etc/GMT-4", - "Asia/Dushanbe": "Etc/GMT-5", - "Asia/Famagusta": "Etc/GMT-2", - "Asia/Gaza": "Etc/GMT-2", - "Asia/Hebron": "Etc/GMT-2", - "Asia/Ho_Chi_Minh": "Etc/GMT-7", - "Asia/Hong_Kong": "Etc/GMT-8", - "Asia/Hovd": "Etc/GMT-7", - "Asia/Irkutsk": "Etc/GMT-8", - "Asia/Jakarta": "Etc/GMT-7", - "Asia/Jayapura": "Etc/GMT-9", - "Asia/Jerusalem": "Etc/GMT-2", - "Asia/Kabul": "Etc/GMT-4:30", - "Asia/Kamchatka": "Etc/GMT-12", - "Asia/Karachi": "Etc/GMT-5", - "Asia/Kathmandu": "Etc/GMT-5:45", - "Asia/Khandyga": "Etc/GMT-9", - "Asia/Kolkata": "Etc/GMT-5:30", - "Asia/Krasnoyarsk": "Etc/GMT-7", - "Asia/Kuala_Lumpur": "Etc/GMT-8", - "Asia/Kuching": "Etc/GMT-8", - "Asia/Kuwait": "Etc/GMT-3", - "Asia/Macau": "Etc/GMT-8", - "Asia/Magadan": "Etc/GMT-11", - "Asia/Makassar": "Etc/GMT-8", - "Asia/Manila": "Etc/GMT-8", - "Asia/Muscat": "Etc/GMT-4", - "Asia/Nicosia": "Etc/GMT-2", - "Asia/Novokuznetsk": "Etc/GMT-7", - "Asia/Novosibirsk": "Etc/GMT-7", - "Asia/Omsk": "Etc/GMT-6", - "Asia/Oral": "Etc/GMT-5", - "Asia/Phnom_Penh": "Etc/GMT-7", - "Asia/Pontianak": "Etc/GMT-7", - "Asia/Pyongyang": "Etc/GMT-9", - "Asia/Qatar": "Etc/GMT-3", - "Asia/Qostanay": "Etc/GMT-6", - "Asia/Qyzylorda": "Etc/GMT-5", - "Asia/Riyadh": "Etc/GMT-3", - "Asia/Sakhalin": "Etc/GMT-11", - "Asia/Samarkand": "Etc/GMT-5", - "Asia/Seoul": "Etc/GMT-9", - "Asia/Shanghai": "Etc/GMT-8", - "Asia/Singapore": "Etc/GMT-8", - "Asia/Srednekolymsk": "Etc/GMT-11", - "Asia/Taipei": "Etc/GMT-8", - "Asia/Tashkent": "Etc/GMT-5", - "Asia/Tbilisi": "Etc/GMT-4", - "Asia/Tehran": "Etc/GMT-3:30", - "Asia/Thimphu": "Etc/GMT-6", - "Asia/Tokyo": "Etc/GMT-9", - "Asia/Tomsk": "Etc/GMT-7", - "Asia/Ulaanbaatar": "Etc/GMT-8", - "Asia/Urumqi": "Etc/GMT-6", - "Asia/Ust-Nera": "Etc/GMT-10", - "Asia/Vientiane": "Etc/GMT-7", - "Asia/Vladivostok": "Etc/GMT-10", - "Asia/Yakutsk": "Etc/GMT-9", - "Asia/Yangon": "Etc/GMT-6:30", - "Asia/Yekaterinburg": "Etc/GMT-5", - "Asia/Yerevan": "Etc/GMT-4", - "Atlantic/Azores": "Etc/GMT+1", - "Atlantic/Bermuda": "Etc/GMT+4", - "Atlantic/Canary": "Etc/GMT", - "Atlantic/Cape_Verde": "Etc/GMT+1", - "Atlantic/Faroe": "Etc/GMT", - "Atlantic/Madeira": "Etc/GMT", - "Atlantic/Reykjavik": "Etc/GMT", - "Atlantic/South_Georgia": "Etc/GMT+2", - "Atlantic/Stanley": "Etc/GMT+3", - "Australia/Adelaide": "Etc/GMT-9:30", - "Australia/Brisbane": "Etc/GMT-10", - "Australia/Broken_Hill": "Etc/GMT-9:30", - "Australia/Currie": "Etc/GMT-10", - "Australia/Darwin": "Etc/GMT-9:30", - "Australia/Eucla": "Etc/GMT-8:45", - "Australia/Hobart": "Etc/GMT-10", - "Australia/Lindeman": "Etc/GMT-10", - "Australia/Lord_Howe": "Etc/GMT-10:30", - "Australia/Melbourne": "Etc/GMT-10", - "Australia/Perth": "Etc/GMT-8", - "Australia/Sydney": "Etc/GMT-10", - "Europe/Amsterdam": "Etc/GMT-1", - "Europe/Andorra": "Etc/GMT-1", - "Europe/Astrakhan": "Etc/GMT-4", - "Europe/Athens": "Etc/GMT-2", - "Europe/Belgrade": "Etc/GMT-1", - "Europe/Berlin": "Etc/GMT-1", - "Europe/Bratislava": "Etc/GMT-1", - "Europe/Brussels": "Etc/GMT-1", - "Europe/Bucharest": "Etc/GMT-2", - "Europe/Budapest": "Etc/GMT-1", - "Europe/Busingen": "Etc/GMT-1", - "Europe/Chisinau": "Etc/GMT-2", - "Europe/Copenhagen": "Etc/GMT-1", - "Europe/Dublin": "Etc/GMT", - "Europe/Gibraltar": "Etc/GMT-1", - "Europe/Guernsey": "Etc/GMT", - "Europe/Helsinki": "Etc/GMT-2", - "Europe/Isle_of_Man": "Etc/GMT", - "Europe/Istanbul": "Etc/GMT-3", - "Europe/Jersey": "Etc/GMT", - "Europe/Kaliningrad": "Etc/GMT-2", - "Europe/Kyiv": "Etc/GMT-2", - "Europe/Kirov": "Etc/GMT-3", - "Europe/Lisbon": "Etc/GMT", - "Europe/Ljubljana": "Etc/GMT-1", - "Europe/London": "Etc/GMT", - "Europe/Luxembourg": "Etc/GMT-1", - "Europe/Madrid": "Etc/GMT-1", - "Europe/Malta": "Etc/GMT-1", - "Europe/Mariehamn": "Etc/GMT-2", - "Europe/Minsk": "Etc/GMT-3", - "Europe/Monaco": "Etc/GMT-1", - "Europe/Oslo": "Etc/GMT-1", - "Europe/Paris": "Etc/GMT-1", - "Europe/Podgorica": "Etc/GMT-1", - "Europe/Prague": "Etc/GMT-1", - "Europe/Riga": "Etc/GMT-2", - "Europe/Rome": "Etc/GMT-1", - "Europe/Samara": "Etc/GMT-4", - "Europe/San_Marino": "Etc/GMT-1", - "Europe/Sarajevo": "Etc/GMT-1", - "Europe/Saratov": "Etc/GMT-4", - "Europe/Simferopol": "Etc/GMT-3", - "Europe/Skopje": "Etc/GMT-1", - "Europe/Sofia": "Etc/GMT-2", - "Europe/Stockholm": "Etc/GMT-1", - "Europe/Tallinn": "Etc/GMT-2", - "Europe/Tirane": "Etc/GMT-1", - "Europe/Ulyanovsk": "Etc/GMT-4", - "Europe/Uzhgorod": "Etc/GMT-2", - "Europe/Vaduz": "Etc/GMT-1", - "Europe/Vatican": "Etc/GMT-1", - "Europe/Vienna": "Etc/GMT-1", - "Europe/Vilnius": "Etc/GMT-2", - "Europe/Volgograd": "Etc/GMT-3", - "Europe/Warsaw": "Etc/GMT-1", - "Europe/Zagreb": "Etc/GMT-1", - "Europe/Zaporozhye": "Etc/GMT-2", - "Europe/Zurich": "Etc/GMT-1", - "Indian/Antananarivo": "Etc/GMT-3", - "Indian/Chagos": "Etc/GMT-6", - "Indian/Christmas": "Etc/GMT-7", - "Indian/Cocos": "Etc/GMT-6:30", - "Indian/Comoro": "Etc/GMT-3", - "Indian/Kerguelen": "Etc/GMT-5", - "Indian/Mahe": "Etc/GMT-4", - "Indian/Maldives": "Etc/GMT-5", - "Indian/Mauritius": "Etc/GMT-4", - "Indian/Mayotte": "Etc/GMT-3", - "Indian/Reunion": "Etc/GMT-4", - "Pacific/Apia": "Etc/GMT-13", - "Pacific/Auckland": "Etc/GMT-12", - "Pacific/Bougainville": "Etc/GMT-11", - "Pacific/Chatham": "Etc/GMT-12:45", - "Pacific/Chuuk": "Etc/GMT-10", - "Pacific/Easter": "Etc/GMT+6", - "Pacific/Efate": "Etc/GMT-11", - "Pacific/Enderbury": "Etc/GMT-13", - "Pacific/Fakaofo": "Etc/GMT-13", - "Pacific/Fiji": "Etc/GMT-12", - "Pacific/Funafuti": "Etc/GMT-12", - "Pacific/Galapagos": "Etc/GMT+6", - "Pacific/Gambier": "Etc/GMT+9", - "Pacific/Guadalcanal": "Etc/GMT-11", - "Pacific/Guam": "Etc/GMT-10", - "Pacific/Honolulu": "Etc/GMT+10", - "Pacific/Kiritimati": "Etc/GMT-14", - "Pacific/Kosrae": "Etc/GMT-11", - "Pacific/Kwajalein": "Etc/GMT-12", - "Pacific/Majuro": "Etc/GMT-12", - "Pacific/Marquesas": "Etc/GMT+9:30", - "Pacific/Midway": "Etc/GMT+11", - "Pacific/Nauru": "Etc/GMT-12", - "Pacific/Niue": "Etc/GMT+11", - "Pacific/Norfolk": "Etc/GMT-11", - "Pacific/Noumea": "Etc/GMT-11", - "Pacific/Pago_Pago": "Etc/GMT+11", - "Pacific/Palau": "Etc/GMT-9", - "Pacific/Pitcairn": "Etc/GMT+8", - "Pacific/Pohnpei": "Etc/GMT-11", - "Pacific/Port_Moresby": "Etc/GMT-10", - "Pacific/Rarotonga": "Etc/GMT+10", - "Pacific/Saipan": "Etc/GMT-10", - "Pacific/Tahiti": "Etc/GMT+10", - "Pacific/Tarawa": "Etc/GMT-12", - "Pacific/Tongatapu": "Etc/GMT-13", - "Pacific/Wake": "Etc/GMT-12", - "Pacific/Wallis": "Etc/GMT-12" -}