Mappage du code postal américain sur le fuseau horaire [fermé]


84

Lorsque les utilisateurs s'inscrivent avec notre application, nous pouvons déduire leur code postal lorsque nous les validons par rapport à une base de données nationale. Quelle serait la meilleure façon de déterminer une bonne estimation potentielle de leur fuseau horaire à partir de ce code postal?

Nous essayons de minimiser la quantité de données que nous devons leur demander explicitement. Ils pourront définir manuellement le fuseau horaire plus tard si notre meilleure estimation est erronée. Je me rends compte que les codes postaux n'aideront pas à déterminer le fuseau horaire en dehors des États-Unis, mais dans ce cas, nous devrons quand même demander manuellement, et nous traitons principalement avec les États-Unis.

J'ai trouvé beaucoup de bases de données de codes postaux, et jusqu'à présent, seules quelques-unes contiennent des informations sur le fuseau horaire, mais celles qui ne le sont pas ne sont pas gratuites, comme celle-ci . S'il est absolument nécessaire de payer un abonnement à un service pour ce faire, cela n'en vaudra pas la peine et nous devrons simplement demander explicitement aux utilisateurs.

Bien que le langage ne soit pas particulièrement pertinent car je peux probablement convertir les choses si nécessaire, nous utilisons PHP et MySQL.


2
+1 pour une question sur les devinettes
Chris McCall

Réponses:


37

Je viens de trouver une base de données zip gratuite qui comprend le décalage horaire et la participation à l'heure d'été. J'aime la réponse d'Erik J, car cela m'aiderait à choisir le fuseau horaire réel plutôt que le décalage (parce que vous ne pouvez jamais être complètement sûr des règles), mais je pense que je pourrais commencer par ceci et essayer de trouver la meilleure correspondance de fuseau horaire en fonction de la configuration offset / dst. Je pense que je pourrais essayer de mettre en place une version simple de la réponse de Development 4.0 pour vérifier ce que j'obtiens des informations zip comme test de cohérence. Ce n'est certainement pas aussi simple que je l'espère, mais une combinaison devrait me donner au moins 90% de certitude sur le fuseau horaire d'un utilisateur.


@Doug: Tout ce qui concerne le GeoCoding ne sera jamais correct à 100%, d'autant plus lorsque vous n'agissez qu'au niveau ZIP. Pourtant, si vous pouvez avoir raison 90% + du temps, ce sera probablement un avantage pour vos utilisateurs. Le pire que vous soyez susceptible d'être absent est d'une heure.
Eric J.

3
attention, les bases de données zip gratuites sont presque toujours obsolètes, puisque le service postal change ce fichier tous les mois. voir aussi semaphorecorp.com/cgi/zip5.html
joe snyder

Ce lien soulève de bons points, mais comme je l'utilise simplement pour deviner la région générale (et permettre des corrections), je ne devrais pas avoir à m'inquiéter trop. À moins qu'un code postal ne puisse chevaucher plusieurs fuseaux horaires - mais dans ce cas, c'est déjà un cas extrême, et comme nous ne demanderons jamais les adresses des utilisateurs, nous ne serons pas en mesure de les utiliser pour valider davantage. Mais en effet, il serait probablement utile pour nous de nous abonner à un avant la mise en ligne, pour rester à jour. Le gratuit est au moins bon pour les tests.
Doug Kavendek

2
@joesnyder Link est cassé, pourriez-vous mettre à jour ou au moins expliquer ce qu'il y avait?
dlsso


26

La plupart des états sont dans exactement un fuseau horaire (bien qu'il y ait quelques exceptions). La plupart des codes postaux ne traversent pas les frontières des États (bien qu'il y ait quelques exceptions).

Vous pouvez rapidement créer votre propre liste de fuseaux horaires par zip en combinant ces faits.

Voici une liste des plages de codes postaux par état et une liste d' états par fuseau horaire .

Vous pouvez voir les limites des codes postaux et les comparer à la carte des fuseaux horaires en utilisant ce lien , ou Google Earth, pour mapper les zips aux fuseaux horaires pour les États qui sont divisés par une ligne de fuseau horaire.

La majorité des pays non américains avec lesquels vous traitez se trouvent probablement dans exactement un fuseau horaire (encore une fois, il y a des exceptions). En fonction de vos besoins, vous voudrez peut-être regarder d'où viennent vos principaux visiteurs non américains et rechercher simplement leur fuseau horaire.


1
Wow, quelles sont les exceptions?
Hamish Grubijan

5
@Hamish: Exceptions pour les états dans plusieurs fuseaux horaires que vous pouvez voir dans le lien Wikipédia (états par fuseau horaire). Mon collègue est en train de mapper les ZIP aux États au moment où nous parlons et est tombé sur quelques ZIP qui traversent les frontières des États. Un exemple est 42223.
Eric J.

2
Notez également que certains États (seulement l'Arizona et Hawaï je pense ) n'observent pas l'heure d'été.
Jon-Eric

1
Les États du nord-ouest des États-Unis ont un million et un codes postaux par État; avertissement juste.
Qix - MONICA A ÉTÉ MISTREATED

1
C'est bien plus que quelques exceptions. timesemperature.com/tzus/indiana_time_zone.shtml
Chris Moschini

12

J'ai créé une table de base de données MySQL Open-Source (sous licence MIT) qui fait des références croisées entre les codes postaux et les fuseaux horaires et l'ai téléchargée sur sourceforge.net:

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

Il provient de quatre emplacements (API Yahoo PlaceFinder principale - merci @Chris N)

Consultez le fichier README pour plus d'informations et d'instructions.


Avez-vous encore une chance d'avoir le code qui a généré cela? Il a maintenant quelques années et j'espère obtenir un nouvel ensemble de données.
billy

8

Si vous le souhaitez, vous pouvez également avoir une idée du fuseau horaire en demandant au navigateur Josh Fraser d'avoir une belle rédaction ici

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

La deuxième chose que vous devez savoir est de savoir si l'emplacement observe l'heure d'été (DST) ou non. Étant donné que l'heure d'été est toujours observée pendant l'été, nous pouvons comparer le décalage horaire entre deux dates en janvier, au décalage horaire entre deux dates en juin. Si les décalages sont différents, alors nous savons que l'emplacement observe l'heure d'été. Si les décalages sont les mêmes, alors nous savons que l'emplacement N'observe PAS DST.

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
}

Tout le mérite revient à Josh Fraser.

Cela peut vous aider avec les clients en dehors des États-Unis et compléter votre approche zip.

Voici quelques questions SO qui concernent l'obtention du fuseau horaire à partir de javascript


1
Merci! Comme le mentionne Josh sur son site, Jon Nylander a "écrit une solution plus robuste. Utilisez plutôt sa version". Sa version est ici: bitbucket.org/pellepim/jstimezonedetect
Brad Parks

6

Google a une API spécifique pour cela: https://developers.google.com/maps/documentation/timezone/

par exemple: 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"
}

Ils nécessitent un horodatage unix sur la chaîne de requête. À partir de la réponse renvoyée, il semble qu'il timeZoneNameprenne en compte l'heure d'été, en fonction de l'horodatage, tandis timeZoneIdque le nom du fuseau horaire est indépendant de l'heure d'été.

Pour mon utilisation, en Python, je ne fais que passer timestamp=0et utiliser la timeZoneIdvaleur pour obtenir un tz_infoobjet de pytz , je peux ensuite l'utiliser pour localiser une date / heure particulière dans mon propre code.

Je crois que pour PHP de la même manière, vous pouvez trouver "America / New_York" dans http://pecl.php.net/package/timezonedb


4
Notez que la licence de l'API de géocodage de Google vous oblige à utiliser les résultats pour les afficher sur une carte ...
Josh

@Josh Voulez-vous dire que je ne peux pas utiliser l'API de géocodage pour saisir un emplacement dans le but de déterminer le fuseau horaire à cet emplacement?
Cruncher

2
À partir de la page des règles: "Vous pouvez afficher les résultats de l'API Time Zone sur une carte Google, ou sans carte. Si vous souhaitez afficher les résultats de l'API Time Zone sur une carte, ces résultats doivent être affichés sur une carte Google. C'est interdit pour utiliser les données de l'API Time Zone sur une carte qui n'est pas une carte Google. " développeurs.google.com
maps

4

Ruby gem pour convertir le code postal en fuseau horaire: https://github.com/Katlean/TZip (dérivé de https://github.com/farski/TZip ).

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

C'est rapide, petit et n'a pas de dépendances externes, mais gardez à l'esprit que les codes postaux ne correspondent pas parfaitement aux fuseaux horaires.


1
La fourche d'origine TZip et Katlean est bonne, mais pas précise à 100%. Certains codes postaux (probablement introduits ces dernières années) ne sont pas pris en compte.
bigtex777

1

J'ai travaillé sur ce problème pour mon propre site et j'ai l'impression d'avoir trouvé une très bonne solution

1) Attribuez des fuseaux horaires à tous les états avec un seul fuseau horaire (la plupart des états)

et puis soit

2a) utiliser la solution js ( Javascript / PHP et fuseaux horaires ) pour les états restants

ou

2b) utiliser une base de données comme celle liée ci-dessus par @Doug.

De cette façon, vous pouvez trouver tz à un prix avantageux (et très précisément!) Pour la majorité de vos utilisateurs, puis utiliser l'une des autres méthodes plus coûteuses pour l'obtenir pour le reste des États.

Pas super élégant, mais me semblait mieux que d'utiliser js ou une base de données pour chaque utilisateur.


1

En plus de la réponse de Doug Kavendek. On pourrait utiliser l'approche suivante pour se rapprocher de tz_database.

  1. Télécharger [Base de données gratuite sur la latitude et la longitude des codes postaux]
  2. Télécharger [Un fichier de formes des fuseaux horaires TZ du monde]
  3. Utilisez n'importe quelle bibliothèque gratuite pour l'interrogation de fichiers de formes (par exemple .NET Easy GIS .NET , LGPL).
    var shapeFile = nouveau ShapeFile (shapeFilePath);
    var shapeIndex = shapeFile.GetShapeIndexContainingPoint (new PointD (long, lat), 0D);
    var attrValues ​​= shapeFile.GetAttributeFieldValues ​​(shapeIndex);
    var timeZoneId = attrValues ​​[0];

PS Impossible d'insérer tous les liens: (Veuillez donc utiliser la recherche.


1

Cela téléchargera un fichier yaml qui mappera tous les fuseaux horaires à un tableau de leurs codes postaux:

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

par exemple

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

Si vous préférez les fuseaux horaires raccourcis, vous pouvez exécuter celui-ci:

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

par exemple

"EDT" => ["00100", "00101", "00102", "00103", "00104", ...]
"CDT" => ["35000", "35001", "35002", "35003", "35004", ...]
etc...

1
Cela inclut 96941 (Micronésie) comme étant à l'heure du Pacifique, et inclut 83500 comme code postal dans l'heure du Pacifique, mais je ne crois pas que cela existe aux États-Unis. Comment les données ont-elles été créées?
Justin Blank le



0

Il existe en fait une excellente API Google pour cela. Il prend un emplacement et renvoie le fuseau horaire de cet emplacement. Devrait être assez simple pour créer un script bash ou python pour obtenir les résultats pour chaque adresse dans un fichier CSV ou une base de données, puis enregistrer les informations de fuseau horaire.

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

Demande de point de terminaison:

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

Réponse:

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

il convient de noter que l'API coûte 5 $ pour 1 000 appels.
FlyingZebra1
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.