Mapowanie kodu pocztowego w USA na strefę czasową [zamknięte]

84

Kiedy użytkownicy rejestrują się w naszej aplikacji, jesteśmy w stanie określić ich kod pocztowy, porównując go z krajową bazą danych. Jaki byłby najlepszy sposób określenia dobrego potencjalnego zgadywania ich strefy czasowej na podstawie tego kodu pocztowego?

Staramy się zminimalizować ilość danych, o które wyraźnie musimy ich prosić. Będą mogli ręcznie ustawić strefę czasową później, jeśli nasze najlepsze przypuszczenie się nie powiedzie. Zdaję sobie sprawę, że kody pocztowe nie pomogą w ustaleniu strefy czasowej poza Stanami Zjednoczonymi, ale w takim przypadku i tak musielibyśmy ręcznie zapytać, a mimo to mamy do czynienia głównie z USA.

Znalazłem wiele baz danych z kodami pocztowymi i jak dotąd tylko kilka zawiera informacje o strefach czasowych, ale te, które je zawierają, nie są darmowe, takie jak ta . Jeśli absolutnie konieczne jest wykupienie abonamentu na usługę, aby to zrobić, to nie będzie tego warte i będziemy musieli tylko wyraźnie zapytać użytkowników.

Chociaż język nie jest szczególnie istotny, ponieważ prawdopodobnie mogę konwertować rzeczy, które są potrzebne, używamy PHP i MySQL.

Doug Kavendek
źródło
2
+1 za pytanie o zgadywanie
Chris McCall

Odpowiedzi:

37

Właśnie znalazłem darmową bazę danych zip, która zawiera przesunięcie czasu i udział w DST. Podoba mi się odpowiedź Erika J., ponieważ pomogłaby mi wybrać rzeczywistą strefę czasową, a nie tylko przesunięcie (ponieważ nigdy nie można być całkowicie pewnym reguł), ale myślę, że mogę zacząć od tego i poprosić o znajdź najlepsze dopasowanie strefy czasowej na podstawie konfiguracji przesunięcia / czasu letniego. Myślę, że mogę spróbować skonfigurować prostą wersję odpowiedzi Development 4.0, aby sprawdzić, co otrzymuję z informacji zip jako test poczytalności. To zdecydowanie nie jest tak proste, jak bym miał nadzieję, ale połączenie powinno dać mi przynajmniej 90% pewności co do strefy czasowej użytkownika.

Doug Kavendek
źródło
@Doug: Wszystko, co odnosi się do GeoCoding, nigdy nie będzie w 100% poprawne, tym bardziej, że działasz tylko na poziomie ZIP. Mimo to, jeśli możesz mieć rację w 90% + przypadków, prawdopodobnie będzie to korzystne dla użytkowników. Najgorsze, że prawdopodobnie będziesz wolny, to godzina.
Eric J.
3
uważaj, darmowe bazy danych zip są prawie zawsze przestarzałe, ponieważ poczta zmienia ten plik co miesiąc. zobacz także semaphorecorp.com/cgi/zip5.html
joe snyder.
To łącze prowadzi do kilku dobrych punktów, ale ponieważ używam go tylko do zgadywania ogólnego regionu (i pozwalając na poprawki), nie powinienem się zbytnio martwić. O ile kod pocztowy nie może obejmować wielu stref czasowych - ale w tym przypadku jest to już przypadek skrajny, a ponieważ nigdy nie będziemy pytać o adresy użytkowników, nie będziemy mogli ich użyć do dalszej weryfikacji. Ale rzeczywiście, prawdopodobnie przydałoby się nam subskrybowanie jednego z nich, zanim wszystko zacznie działać, aby być na bieżąco. Bezpłatny jest przynajmniej dobry do testowania.
Doug Kavendek
2
@joesnyder Link jest uszkodzony, czy mógłbyś zaktualizować lub przynajmniej wyjaśnić, co tam było?
dlsso
26

Większość stanów znajduje się dokładnie w jednej strefie czasowej (choć jest kilka wyjątków). Większość kodów pocztowych nie przekracza granic państwowych (choć jest kilka wyjątków).

Możesz szybko stworzyć własną listę stref czasowych według kodu pocztowego, łącząc te fakty.

Oto lista zakresów kodów pocztowych według stanu i lista stanów według strefy czasowej .

Możesz zobaczyć granice kodów pocztowych i porównać je z mapą stref czasowych za pomocą tego linku lub Google Earth, aby zamapować suwaki na strefy czasowe dla stanów podzielonych linią strefy czasowej.

Większość krajów spoza USA, z którymi masz do czynienia, znajduje się prawdopodobnie w dokładnie jednej strefie czasowej (znowu są wyjątki). W zależności od potrzeb możesz sprawdzić, skąd pochodzą Twoi najliczniejsi użytkownicy spoza USA i po prostu sprawdzić ich strefę czasową.

Eric J.
źródło
1
Wow, jakie są wyjątki?
Hamish Grubijan
5
@ Hamish: Wyjątki dla stanów w wielu strefach czasowych, które można zobaczyć w linku do Wikipedii (stany według strefy czasowej). Mój kolega mapuje pliki ZIP na stany, gdy mówimy, i natknął się na kilka ZIP, które przecinają linie stanów. Jednym z przykładów jest 42223.
Eric J.
2
Zauważ również, że w niektórych stanach ( chyba tylko Arizona i Hawaje ) nie obowiązuje czas letni.
Jon-Eric
1
Stany na północnym zachodzie Stanów Zjednoczonych mają milion i jeden kod pocztowy na stan; uczciwe ostrzeżenie.
Qix - MONICA ZOSTAŁA POGŁĘBIONA MARZEC
1
To znacznie więcej niż kilka wyjątków. timeremperature.com/tzus/indiana_time_zone.shtml
Chris Moschini
12

Utworzyłem tabelę bazy danych MySQL typu Open Source (na licencji MIT), która zawiera odniesienia do kodów pocztowych i stref czasowych i przesłałem ją na sourceforge.net:

http://sourceforge.net/projects/zip2timezone/files/

Pochodzi z czterech lokalizacji (podstawowy interfejs API Yahoo PlaceFinder - dzięki @Chris N)

Więcej informacji i instrukcji zawiera plik README.

chriv
źródło
Czy nadal masz kod, który to wygenerował? Ma teraz kilka lat i mam nadzieję, że otrzymam nowy zestaw danych.
billy
8

Jeśli chcesz, możesz również poczuć strefę czasową, prosząc przeglądarkę Josh Fraser o fajny opis tutaj

var rightNow = new Date();
var jan1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0);
var temp = jan1.toGMTString();
var jan2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1));
var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60);

Drugą rzeczą, którą musisz wiedzieć, jest to, czy w danej lokalizacji przestrzega się czasu letniego (DST), czy nie. Ponieważ latem zawsze obserwuje się czas letni, możemy porównać przesunięcie czasu między dwiema datami w styczniu, z przesunięciem czasowym między dwiema datami w czerwcu. Jeśli przesunięcia są różne, wiemy, że w danej lokalizacji jest przestrzegany czas letni. Jeśli przesunięcia są takie same, wiemy, że w miejscu nie przestrzega się czasu letniego.

var june1 = new Date(rightNow.getFullYear(), 6, 1, 0, 0, 0, 0);
temp = june1.toGMTString();
var june2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1));
var daylight_time_offset = (june1 - june2) / (1000 * 60 * 60);
var dst;
if (std_time_offset == daylight_time_offset) {
    dst = "0"; // daylight savings time is NOT observed
} else {
    dst = "1"; // daylight savings time is observed
}

Wszystko to zasługa Josha Frasera.

Może to pomóc w przypadku klientów spoza Stanów Zjednoczonych i może uzupełniać Twoje podejście do zip.

Oto pytania SO, które dotyczą pobierania strefy czasowej z javascript

Rozwój 4.0
źródło
1
dzięki! Jak wspomina Josh na swojej stronie, Jon Nylander „napisał bardziej niezawodne rozwiązanie. Zamiast tego użyj jego wersji”. Jego wersja jest tutaj: bitbucket.org/pellepim/jstimezonedetect
Brad Parks.
6

Google ma do tego specjalny interfejs API: https://developers.google.com/maps/documentation/timezone/

np .: https://maps.googleapis.com/maps/api/timezone/json?location=40.704822,-74.0137431×tamp=0

{
  dstOffset: 0,
  rawOffset: -18000,
  status: "OK",
  timeZoneId: "America/New_York",
  timeZoneName: "Eastern Standard Time"
}

Wymagają uniksowego znacznika czasu w kwerendzie. Z zwróconej odpowiedzi wynika, że timeZoneNameuwzględnia ona czas letni na podstawie sygnatury czasowej, a timeZoneIdjest niezależną od czasu letniego nazwą strefy czasowej.

Na mój użytek, w Pythonie, po prostu przekazuję timestamp=0i używam timeZoneIdwartości, aby uzyskać tz_infoobiekt z pytz , mogę następnie użyć tego do zlokalizowania dowolnej konkretnej daty i godziny w moim własnym kodzie.

Uważam, że podobnie dla PHP można znaleźć "America / New_York" w http://pecl.php.net/package/timezonedb

Anentropowy
źródło
4
Pamiętaj, że licencjonowanie interfejsu API geokodowania Google wymaga wykorzystania wyników do wyświetlania na mapie ...
Josh
@Josh Czy chcesz powiedzieć, że nie mogę użyć interfejsu API geokodowania do pobrania lokalizacji w celu określenia strefy czasowej w tej lokalizacji?
Cruncher
2
Ze strony zasad: „Możesz wyświetlać wyniki interfejsu API strefy czasowej na mapie Google lub bez mapy. Jeśli chcesz wyświetlić wyniki interfejsu API strefy czasowej na mapie, wyniki te muszą być wyświetlane na mapie Google. Jest to zabronione używać danych interfejsu API strefy czasowej na mapie, która nie jest mapą Google ”. developers.google.com/maps/documentation/timezone/policies
tmorell
4

Klejnot Ruby do konwersji kodu pocztowego na strefę czasową: https://github.com/Katlean/TZip (rozwidlony z https://github.com/farski/TZip ).

> ActiveSupport::TimeZone.find_by_zipcode('90029')
 => "Pacific Time (US & Canada)"

Jest szybki, mały i nie ma żadnych zewnętrznych zależności, ale pamiętaj, że kody pocztowe po prostu nie są idealnie mapowane do stref czasowych.

mkirk
źródło
1
Zarówno oryginalny TZip, jak i widelec Katlean są dobre, ale nie w 100% dokładne. Niektóre kody pocztowe (prawdopodobnie wprowadzone w ciągu ostatnich kilku lat) nie są uwzględniane.
bigtex777
1

Pracowałem nad tym problemem dla własnej witryny i czuję, że znalazłem całkiem dobre rozwiązanie

1) Przypisz strefy czasowe do wszystkich stanów z tylko jedną strefą czasową (większość stanów)

a potem albo

2a) użyj rozwiązania js ( Javascript / PHP i strefy czasowe ) dla pozostałych stanów

lub

2b) użyj bazy danych, takiej jak ta, do której link znajduje się powyżej @Doug.

W ten sposób możesz znaleźć tz tanio (i bardzo dokładnie!) Dla większości użytkowników, a następnie użyć jednej z innych, droższych metod, aby uzyskać go dla pozostałych stanów.

Niezbyt eleganckie, ale wydawało mi się lepsze niż używanie js lub bazy danych dla każdego użytkownika.

Matt Parrilla
źródło
1

Oprócz odpowiedzi Douga Kavendeka. Aby zbliżyć się do tz_database, można zastosować następujące podejście.

  1. Pobierz [bezpłatną bazę danych długości i szerokości geograficznych kodów pocztowych]
  2. Pobierz [Shapefile of the TZ timezones of the world]
  3. Użyj dowolnej darmowej biblioteki do odpytywania Shapefile (np. .NET Easy GIS .NET , LGPL).
    var shapeFile = new ShapeFile (shapeFilePath);
    var shapeIndex = shapeFile.GetShapeIndexContainingPoint (new PointD (long, lat), 0D);
    var attrValues ​​= shapeFile.GetAttributeFieldValues ​​(shapeIndex);
    var timeZoneId = attrValues ​​[0];

PS Nie mogę wstawić wszystkich linków :( Więc użyj wyszukiwania.

Dmitriy Zubrilin
źródło
1

Spowoduje to pobranie pliku yaml, który zamapuje wszystkie strefy czasowe na tablicę ich kodów pocztowych:

curl https://gist.githubusercontent.com/anonymous/01bf19b21da3424f6418/raw/0d69a384f55c6f68244ddaa07e0c2272b44cb1de/timezones_to_zipcodes.yml > timezones_to_zipcodes.yml

na przykład

"Eastern Time (US & Canada)" => ["00100", "00101", "00102", "00103", "00104", ...]
"Central Time (US & Canada)" => ["35000", "35001", "35002", "35003", "35004", ...]
etc...

Jeśli wolisz skrócone strefy czasowe, możesz uruchomić tę:

curl https://gist.githubusercontent.com/anonymous/4e04970131ca82945080/raw/e85876daf39a823e54d17a79258b170d0a33dac0/timezones_to_zipcodes_short.yml > timezones_to_zipcodes.yml

na przykład

"EDT" => ["00100", "00101", "00102", "00103", "00104", ...]
"CDT" => ["35000", "35001", "35002", "35003", "35004", ...]
etc...
BananaNeil
źródło
1
Obejmuje to 96941 (Mikronezja) jako czas pacyficzny i obejmuje 83500 jako kod pocztowy w czasie pacyficznym, ale nie sądzę, aby istniał w Stanach Zjednoczonych. Jak powstały dane?
Justin Blank
0

W rzeczywistości jest do tego świetny interfejs API Google. Pobiera lokalizację i zwraca strefę czasową dla tej lokalizacji. Powinno być wystarczająco proste, aby utworzyć skrypt bash lub python, aby uzyskać wyniki dla każdego adresu w pliku CSV lub bazie danych, a następnie zapisać informacje o strefie czasowej.

https://developers.google.com/maps/documentation/timezone/start

Punkt końcowy żądania:

https://maps.googleapis.com/maps/api/timezone/json?location=38.908133,-77.047119&timestamp=1458000000&key=YOUR_API_KEY

Odpowiedź:

{
   "dstOffset" : 3600,
   "rawOffset" : -18000,
   "status" : "OK",
   "timeZoneId" : "America/New_York",
   "timeZoneName" : "Eastern Daylight Time"
}
Anonmily
źródło
należy zauważyć, że api to 5 $ za 1k wywołań.
FlyingZebra