Zuordnung der US-Postleitzahl zur Zeitzone [geschlossen]

84

Wenn sich Benutzer bei unserer App registrieren, können wir ihre Postleitzahl ableiten, wenn wir sie anhand einer nationalen Datenbank validieren. Was wäre der beste Weg, um anhand dieser Postleitzahl eine gute potenzielle Schätzung ihrer Zeitzone zu ermitteln?

Wir versuchen, die Datenmenge zu minimieren, nach der wir sie explizit fragen müssen. Sie können die Zeitzone später manuell einstellen, wenn unsere beste Vermutung falsch ist. Mir ist klar, dass Postleitzahlen nicht dazu beitragen, die Zeitzone außerhalb der USA herauszufinden, aber in diesem Fall müssten wir trotzdem manuell nachfragen, und wir beschäftigen uns unabhängig davon überwiegend mit den USA.

Ich habe viele Postleitzahlendatenbanken gefunden, und bisher enthalten nur wenige Zeitzoneninformationen, aber diejenigen, die nicht kostenlos sind, wie diese . Wenn es dazu unbedingt erforderlich ist, ein Abonnement für einen Dienst zu bezahlen, lohnt es sich nicht und wir müssen die Benutzer nur explizit fragen.

Obwohl die Sprache nicht besonders relevant ist, da ich wahrscheinlich Dinge konvertieren kann, die benötigt werden, verwenden wir PHP und MySQL.

Doug Kavendek
quelle
2
+1 für Fragen zum Raten
Chris McCall

Antworten:

37

Ich habe gerade eine kostenlose Zip-Datenbank gefunden , die Zeitversatz und Teilnahme an der Sommerzeit enthält. Ich mag die Antwort von Erik J, da sie mir helfen würde, die tatsächliche Zeitzone und nicht nur den Versatz zu wählen (weil Sie sich bei den Regeln nie ganz sicher sein können), aber ich denke, ich könnte damit beginnen und es versuchen lassen Finden Sie die beste Zeitzonenübereinstimmung basierend auf der Offset / dst-Konfiguration. Ich denke, ich kann versuchen, eine einfache Version der Antwort von Development 4.0 einzurichten, um zu überprüfen, was ich aus den Zip-Informationen als Vernunfttest erhalte. Es ist definitiv nicht so einfach, wie ich es mir erhoffen würde, aber eine Kombination sollte mir mindestens 90% der Zeitzone eines Benutzers geben.

Doug Kavendek
quelle
@Doug: Alles, was sich auf GeoCoding bezieht, wird niemals 100% korrekt sein, umso mehr, wenn Sie nur auf ZIP-Ebene handeln. Wenn Sie jedoch in über 90% der Fälle korrekt sein können, ist dies wahrscheinlich ein Vorteil für Ihre Benutzer. Das Schlimmste, was Sie wahrscheinlich tun werden, ist eine Stunde.
Eric J.
3
Achtung, kostenlose Zip-Datenbanken sind fast immer veraltet, da der Postdienst diese Datei monatlich ändert. siehe auch semaphorecorp.com/cgi/zip5.html
joe snyder
Dieser Link bringt einige gute Punkte auf den Punkt, aber da ich dies nur verwende, um die allgemeine Region zu erraten (und Korrekturen zuzulassen), sollte ich mir keine Sorgen machen müssen. Es sei denn, eine Postleitzahl kann mehrere Zeitzonen überspannen. In diesem Fall handelt es sich jedoch bereits um einen Randfall. Da wir niemals nach Benutzeradressen fragen, können wir diese nicht zur weiteren Validierung verwenden. Aber in der Tat wäre es wahrscheinlich nützlich, wenn wir eines abonnieren würden, bevor die Dinge live gehen, um auf dem neuesten Stand zu bleiben. Der kostenlose ist zumindest gut zum Testen.
Doug Kavendek
2
@joesnyder Link ist kaputt, könntest du aktualisieren oder zumindest erklären, was da war?
dlsso
24

Die meisten Staaten liegen in genau einer Zeitzone (obwohl es einige Ausnahmen gibt). Die meisten Postleitzahlen überschreiten keine Staatsgrenzen (obwohl es einige Ausnahmen gibt).

Sie können schnell eine eigene Liste von Zeitzonen pro Postleitzahl erstellen, indem Sie diese Fakten kombinieren.

Hier ist eine Liste der Postleitzahlbereiche pro Bundesstaat und eine Liste der Bundesstaaten pro Zeitzone .

Über diesen Link oder Google Earth können Sie die Grenzen von Postleitzahlen anzeigen und mit der Zeitzonenkarte vergleichen , um Reißverschlüsse Zeitzonen für die Zustände zuzuordnen, die durch eine Zeitzonenlinie getrennt sind.

Die Mehrheit der Nicht-US-Länder, mit denen Sie zu tun haben, befindet sich wahrscheinlich in genau einer Zeitzone. Vielleicht möchten Sie sich ansehen, woher Ihre Top-N-Besucher außerhalb der USA kommen, und einfach ihre Zeitzone nachschlagen.

Eric J.
quelle
1
Wow, was sind die Ausnahmen?
Hamish Grubijan
5
@ Hamish: Ausnahmen für Zustände in mehreren Zeitzonen, die Sie im Wikipedia-Link sehen können (Zustände pro Zeitzone). Mein Kollege ordnet während des Gesprächs Postleitzahlen Staaten zu und ist auf einige Postleitzahlen gestoßen, die die Staatsgrenzen überschreiten. Ein Beispiel ist 42223.
Eric J.
2
Beachten Sie auch, dass einige Bundesstaaten (nur Arizona und Hawaii, glaube ich ) keine Sommerzeit einhalten.
Jon-Eric
1
Staaten im Nordwesten der USA haben eine Million und eine Postleitzahl pro Staat; faire Warnung.
Qix - MONICA wurde am
1
Es ist viel mehr als ein paar Ausnahmen. timetemperature.com/tzus/indiana_time_zone.shtml
Chris Moschini
12

Ich habe eine Open-Source-MySQL-Datenbanktabelle (MIT-lizenziert) erstellt, die auf Postleitzahlen und Zeitzonen verweist, und sie auf sourceforge.net hochgeladen:

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

Es wird von vier Standorten bezogen (primäre Yahoo PlaceFinder-API - danke @Chris N)

Weitere Informationen und Anweisungen finden Sie in der README-Datei.

chriv
quelle
8

Wenn Sie möchten, können Sie sich auch ein Bild von der Zeitzone machen, indem Sie den Browser fragen. Josh Fraser hat hier eine nette Beschreibung

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);

Das zweite, was Sie wissen müssen, ist, ob der Standort die Sommerzeit (DST) einhält oder nicht. Da die Sommerzeit immer im Sommer eingehalten wird, können wir den Zeitversatz zwischen zwei Daten im Januar mit dem Zeitversatz zwischen zwei Daten im Juni vergleichen. Wenn die Offsets unterschiedlich sind, wissen wir, dass der Standort die Sommerzeit einhält. Wenn die Offsets gleich sind, wissen wir, dass der Ort die Sommerzeit NICHT beachtet.

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
}

Alle Ehre gebührt Josh Fraser.

Dies kann Ihnen bei Kunden außerhalb der USA helfen und Ihren Zip-Ansatz ergänzen.

Hier sind SO-Fragen, die sich mit dem Abrufen der Zeitzone aus Javascript befassen

Entwicklung 4.0
quelle
1
Vielen Dank! Wie Josh auf seiner Website erwähnt, hat Jon Nylander "eine robustere Lösung geschrieben. Verwenden Sie stattdessen seine Version." Seine Version ist hier: bitbucket.org/pellepim/jstimezonedetect
Brad Parks
6

Google hat hierfür eine spezielle API: https://developers.google.com/maps/documentation/timezone/

Beispiel: 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"
}

Sie benötigen einen Unix-Zeitstempel auf dem Querystring. Aus der zurückgegebenen Antwort geht hervor, dass timeZoneNamedie Sommerzeit basierend auf dem Zeitstempel berücksichtigt wird, während timeZoneIdes sich um einen DST-unabhängigen Namen für die Zeitzone handelt.

Für meine Verwendung in Python übergebe ich nur timestamp=0den timeZoneIdWert und verwende ihn , um ein tz_infoObjekt von pytz abzurufen . Anschließend kann ich damit eine bestimmte Datums- und Uhrzeitangabe in meinem eigenen Code lokalisieren.

Ich glaube, für PHP finden Sie "America / New_York" in ähnlicher Weise unter http://pecl.php.net/package/timezonedb

Anentropisch
quelle
4
Beachten Sie, dass Sie für die Lizenzierung der Geokodierungs-API von Google die Ergebnisse für die Anzeige auf einer Karte verwenden müssen ...
Josh
@Josh Wollen Sie damit sagen, dass ich die Geokodierungs-API nicht verwenden kann, um einen Ort zu ermitteln, um die Zeitzone an diesem Ort zu bestimmen?
Cruncher
2
Auf der Richtlinienseite: "Sie können Zeitzonen-API-Ergebnisse auf einer Google Map oder ohne Karte anzeigen. Wenn Sie Zeitzonen-API-Ergebnisse auf einer Karte anzeigen möchten, müssen diese Ergebnisse auf einer Google Map angezeigt werden. Dies ist verboten." Zeitzonen-API-Daten auf einer Karte verwenden, die keine Google-Karte ist. " developer.google.com/maps/documentation/timezone/policies
tmorell
4

Ruby Gem zum Konvertieren der Postleitzahl in die Zeitzone: https://github.com/Katlean/TZip (gegabelt von https://github.com/farski/TZip ).

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

Es ist schnell, klein und hat keine externen Abhängigkeiten. Beachten Sie jedoch, dass Postleitzahlen nicht perfekt auf Zeitzonen abgebildet werden können.

mkirk
quelle
1
Sowohl die Originalgabel von TZip als auch von Katlean sind gut, aber nicht 100% genau. Einige Postleitzahlen (wahrscheinlich in den letzten Jahren eingeführt) werden nicht berücksichtigt.
Bigtex777
1

Ich habe an diesem Problem für meine eigene Website gearbeitet und habe das Gefühl, eine ziemlich gute Lösung gefunden zu haben

1) Weisen Sie allen Zuständen mit nur einer Zeitzone Zeitzonen zu (die meisten Zustände).

und dann auch nicht

2a) Verwenden Sie die js-Lösung ( Javascript / PHP und Zeitzonen für die verbleibenden Zustände )

oder

2b) Verwenden Sie eine Datenbank wie die oben von @Doug verlinkte.

Auf diese Weise können Sie tz für die Mehrheit Ihrer Benutzer billig (und sehr genau!) Finden und dann eine der anderen, teureren Methoden verwenden, um es für den Rest der Staaten zu erhalten.

Nicht super elegant, aber mir schien es besser, als für jeden Benutzer js oder eine Datenbank zu verwenden.

Matt Parrilla
quelle
1

Neben Doug Kavendek Antwort. Man könnte den folgenden Ansatz verwenden, um näher an tz_database heranzukommen.

  1. Download [Kostenlose Postleitzahl-Breiten- und Längengrad-Datenbank]
  2. Download [Ein Shapefile der TZ-Zeitzonen der Welt]
  3. Verwenden Sie eine beliebige freie Bibliothek zum Abfragen von Shapefiles (z. B. .NET Easy GIS .NET , LGPL).
    var shapeFile = new ShapeFile (shapeFilePath);
    var shapeIndex = shapeFile.GetShapeIndexContainingPoint (neuer PointD (lang, lat), 0D);
    var attrValues ​​= shapeFile.GetAttributeFieldValues ​​(shapeIndex);
    var timeZoneId = attrValues ​​[0];

PS Es können nicht alle Links eingefügt werden :( Bitte verwenden Sie die Suche.

Dmitriy Zubrilin
quelle
1

Dadurch wird eine Yaml-Datei heruntergeladen, die alle Zeitzonen einem Array ihrer Postleitzahlen zuordnet:

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

z.B

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

Wenn Sie die verkürzten Zeitzonen bevorzugen, können Sie diese ausführen:

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

z.B

"EDT" => ["00100", "00101", "00102", "00103", "00104", ...]
"CDT" => ["35000", "35001", "35002", "35003", "35004", ...]
etc...
BananaNeil
quelle
1
Dies schließt 96941 (Mikronesien) als in pazifischer Zeit und 83500 als Postleitzahl in pazifischer Zeit ein, aber ich glaube nicht, dass es das in den Vereinigten Staaten gibt. Wie wurden die Daten erstellt?
Justin Blank
0

Dafür gibt es tatsächlich eine großartige Google-API. Es nimmt einen Ort auf und gibt die Zeitzone für diesen Ort zurück. Sollte einfach genug sein, um ein Bash- oder Python-Skript zu erstellen, um die Ergebnisse für jede Adresse in einer CSV-Datei oder -Datenbank zu erhalten, und speichern Sie dann die Zeitzoneninformationen.

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

Endpunkt anfordern:

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

Antwort:

{
   "dstOffset" : 3600,
   "rawOffset" : -18000,
   "status" : "OK",
   "timeZoneId" : "America/New_York",
   "timeZoneName" : "Eastern Daylight Time"
}
Anonmily
quelle
Es sollte beachtet werden, dass die API $ 5 für 1k Anrufe ist.
FlyingZebra1