Asignación del código postal de EE. UU. A la zona horaria [cerrado]

84

Cuando los usuarios se registran en nuestra aplicación, podemos inferir su código postal cuando los validamos con una base de datos nacional. ¿Cuál sería la mejor manera de determinar una buena suposición potencial de su zona horaria a partir de este código postal?

Estamos tratando de minimizar la cantidad de datos que explícitamente tenemos que pedirles. Podrán configurar manualmente la zona horaria más tarde si nuestra mejor suposición es incorrecta. Me doy cuenta de que los códigos postales no ayudarán a determinar la zona horaria fuera de los EE. UU., Pero en ese caso tendríamos que preguntar manualmente de todos modos, y tratamos predominantemente con los EE. UU. Independientemente.

Encontré muchas bases de datos de códigos postales y, hasta ahora, solo algunas contienen información sobre la zona horaria, pero las que la tienen no son gratuitas, como esta . Si es absolutamente necesario pagar una suscripción a un servicio para hacer esto, entonces no valdrá la pena y solo tendremos que preguntar a los usuarios explícitamente.

Aunque el lenguaje no es particularmente relevante ya que probablemente puedo convertir cosas sin importar lo que sea necesario, estamos usando PHP y MySQL.

Doug Kavendek
fuente
2
+1 para preguntas sobre adivinanzas
Chris McCall

Respuestas:

37

Acabo de encontrar una base de datos zip gratuita que incluye compensación de tiempo y participación en DST. Me gusta la respuesta de Erik J, ya que me ayudaría a elegir la zona horaria real en lugar de solo el desplazamiento (porque nunca puedes estar completamente seguro de las reglas), pero creo que podría comenzar con esto e intentarlo encuentre la mejor coincidencia de zona horaria según la configuración de desplazamiento / dst. Creo que puedo intentar configurar una versión simple de la respuesta de Development 4.0 para verificar lo que obtengo de la información del zip como una prueba de cordura. Definitivamente no es tan simple como esperaba, pero una combinación debería darme al menos un 90% seguro de la zona horaria de un usuario.

Doug Kavendek
fuente
@Doug: Todo lo que se relacione con GeoCoding nunca será 100% correcto, más aún cuando solo estás actuando en el nivel ZIP. Aún así, si puede estar en lo correcto el 90% + de las veces, probablemente será un beneficio para sus usuarios. Lo peor que puede perder es una hora.
Eric J.
3
cuidado, las bases de datos zip gratuitas casi siempre están obsoletas, ya que el servicio postal cambia ese archivo mensualmente. ver también semaphorecorp.com/cgi/zip5.html
joe snyder
Ese enlace trae algunos puntos buenos, pero como solo estoy usando esto para adivinar la región general (y permitir correcciones), no debería tener que preocuparme demasiado. A menos que un código postal pueda abarcar varias zonas horarias, pero en ese caso, ya es un caso límite y, dado que nunca solicitaremos las direcciones de los usuarios, no podríamos usarlas para validar más. Pero, de hecho, probablemente sería útil que nos suscribiéramos a uno antes de que las cosas se pusieran en marcha, para mantenernos actualizados. El gratuito es al menos bueno para probar.
Doug Kavendek
2
@joesnyder El enlace está roto, ¿podrías actualizar o al menos explicar qué había?
dlsso
26

La mayoría de los estados se encuentran exactamente en una zona horaria (aunque hay algunas excepciones). La mayoría de los códigos postales no cruzan las fronteras estatales (aunque hay algunas excepciones).

Puede crear rápidamente su propia lista de zonas horarias por código postal combinando esos datos.

Aquí hay una lista de rangos de códigos postales por estado y una lista de estados por zona horaria .

Puede ver los límites de los códigos postales y compararlos con el mapa de la zona horaria utilizando este enlace , o Google Earth, para asignar las cremalleras a las zonas horarias de los estados que están divididos por una línea de zona horaria.

La mayoría de los países que no son de EE. UU. Con los que está tratando probablemente se encuentren exactamente en una zona horaria (nuevamente, hay excepciones). Dependiendo de sus necesidades, es posible que desee ver de dónde provienen sus N visitantes principales que no son de EE. UU. Y simplemente buscar su zona horaria.

Eric J.
fuente
1
Vaya, ¿cuáles son las excepciones?
Hamish Grubijan
5
@Hamish: Excepciones para estados en múltiples zonas horarias que puede ver en el enlace de Wikipedia (estados por zona horaria). Mi colega está mapeando códigos postales a estados mientras hablamos y encontró algunos códigos postales que cruzan las fronteras estatales. Un ejemplo es 42223.
Eric J.
2
También tenga en cuenta que algunos estados ( creo que sólo Arizona y Hawai ) no observan el horario de verano.
Jon-Eric
1
Los estados del noroeste de los EE. UU. Tienen un millón y un códigos postales por estado; advertencia justa.
Qix - MONICA FUE MALTRATADA
1
Es mucho más que unas pocas excepciones. timetemperature.com/tzus/indiana_time_zone.shtml
Chris Moschini
12

Creé una tabla de base de datos MySQL de código abierto (con licencia MIT) que hace referencias cruzadas de códigos postales y zonas horarias y la cargué en sourceforge.net:

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

Se obtiene de cuatro ubicaciones (API principal de Yahoo PlaceFinder, gracias @Chris N)

Consulte el archivo README para obtener más información e instrucciones.

chriv
fuente
¿Alguna posibilidad de que todavía tenga el código que generó eso? Tiene algunos años ahora y espero obtener un conjunto de datos nuevo.
Billy
8

Si lo desea, también puede tener una idea de la zona horaria preguntando al navegador Josh Fraser tiene un buen comentario aquí.

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 segunda cosa que necesita saber es si la ubicación observa el horario de verano (DST) o no. Dado que el horario de verano siempre se observa durante el verano, podemos comparar la diferencia horaria entre dos fechas en enero con la diferencia horaria entre dos fechas en junio. Si las compensaciones son diferentes, entonces sabemos que la ubicación cumple con el horario de verano. Si las compensaciones son las mismas, entonces sabemos que la ubicación NO cumple con el horario de verano.

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
}

Todo el mérito de esto es para Josh Fraser.

Esto podría ayudarlo con clientes fuera de los EE. UU. Y podría complementar su enfoque zip.

Aquí hay algunas preguntas SO relacionadas con la obtención de la zona horaria de javascript

Desarrollo 4.0
fuente
1
¡Gracias! Como menciona Josh en su sitio, Jon Nylander ha "escrito una solución más sólida. Utilice su versión en su lugar". Su versión está aquí: bitbucket.org/pellepim/jstimezonedetect
Brad Parks
6

Google tiene una API específica para esto: https://developers.google.com/maps/documentation/timezone/

por ejemplo: 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"
}

Requieren una marca de tiempo Unix en la cadena de consulta. De la respuesta devuelta, parece que timeZoneNametiene en cuenta el horario de verano, según la marca de tiempo, mientras que timeZoneIdes un nombre independiente de DST para la zona horaria.

Para mi uso, en Python, solo estoy pasando timestamp=0y usando el timeZoneIdvalor para obtener un tz_infoobjeto de pytz , luego puedo usarlo para localizar cualquier fecha y hora en particular en mi propio código.

Creo que para PHP de manera similar puedes encontrar "America / New_York" en http://pecl.php.net/package/timezonedb

Anentrópico
fuente
4
Tenga en cuenta que la licencia para la API de codificación geográfica de Google requiere que utilice los resultados para mostrarlos en un mapa ...
Josh
@Josh ¿Estás diciendo que no puedo usar la API de codificación geográfica para tomar una ubicación con el fin de determinar la zona horaria en esa ubicación?
Cruncher
2
Desde la página de políticas: "Puede mostrar los resultados de la API de zona horaria en un mapa de Google o sin un mapa. Si desea mostrar los resultados de la API de zona horaria en un mapa, estos resultados deben mostrarse en un mapa de Google. Está prohibido para utilizar los datos de la API de zona horaria en un mapa que no es un mapa de Google ". developers.google.com/maps/documentation/timezone/policies
tmorell
4

Ruby gem para convertir el código postal a la zona horaria: https://github.com/Katlean/TZip (bifurcado de https://github.com/farski/TZip ).

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

Es rápido, pequeño y no tiene dependencias externas, pero tenga en cuenta que los códigos postales no se asignan perfectamente a las zonas horarias.

mkirk
fuente
1
Tanto el TZip original como el tenedor de Katlean son buenos, pero no 100% precisos. Algunos códigos postales (probablemente introducidos en los últimos años) no se tienen en cuenta.
bigtex777
1

He estado trabajando en este problema para mi propio sitio y siento que he encontrado una solución bastante buena.

1) Asignar zonas horarias a todos los estados con solo una zona horaria (la mayoría de los estados)

y luego o

2a) use la solución js ( Javascript / PHP y zonas horarias ) para los estados restantes

o

2b) use una base de datos como la que @Doug enlazó anteriormente.

De esta manera, puede encontrar tz de manera económica (¡y con mucha precisión!) Para la mayoría de sus usuarios y luego usar uno de los otros métodos más costosos para obtenerlo para el resto de los estados.

No es súper elegante, pero me pareció mejor que usar js o una base de datos para todos y cada uno de los usuarios.

Matt Parrilla
fuente
1

Además de la respuesta de Doug Kavendek. Se podría usar el siguiente enfoque para acercarse a tz_database.

  1. Descargar [Base de datos gratuita de latitud y longitud del código postal]
  2. Descargar [Un archivo shapefile de las zonas horarias TZ del mundo]
  3. Utilice cualquier biblioteca gratuita para consultas de archivos de forma (por ejemplo, .NET Easy GIS .NET , LGPL).
    var shapeFile = new ShapeFile (shapeFilePath);
    var shapeIndex = shapeFile.GetShapeIndexContainingPoint (nuevo PointD (largo, lat), 0D);
    var attrValues ​​= shapeFile.GetAttributeFieldValues ​​(shapeIndex);
    var timeZoneId = attrValues ​​[0];

PD: No se pueden insertar todos los enlaces :( Por lo tanto, utilice la búsqueda.

Dmitriy Zubrilin
fuente
1

Esto descargará un archivo yaml que mapeará todas las zonas horarias a una matriz de sus códigos postales:

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

p.ej

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

Si prefiere las zonas horarias acortadas, puede ejecutar esta:

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

p.ej

"EDT" => ["00100", "00101", "00102", "00103", "00104", ...]
"CDT" => ["35000", "35001", "35002", "35003", "35004", ...]
etc...
BananaNeil
fuente
1
Esto incluye 96941 (Micronesia) como en la hora del Pacífico e incluye 83500 como código postal en la hora del Pacífico, pero no creo que exista en los Estados Unidos. ¿Cómo se crearon los datos?
Justin Blank
0

De hecho, existe una gran API de Google para esto. Toma una ubicación y devuelve la zona horaria de esa ubicación. Debería ser lo suficientemente simple como para crear un script bash o python para obtener los resultados de cada dirección en un archivo CSV o base de datos y luego guardar la información de la zona horaria.

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

Solicitar punto final:

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

Respuesta:

{
   "dstOffset" : 3600,
   "rawOffset" : -18000,
   "status" : "OK",
   "timeZoneId" : "America/New_York",
   "timeZoneName" : "Eastern Daylight Time"
}
Anónimamente
fuente
Cabe señalar que la API es de $ 5 por 1k llamadas.
FlyingZebra1