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

Cuando los usuarios se registran en nuestra aplicación, podemos inferir su código postal cuando los validamos contra una base de datos nacional. ¿Cuál sería la mejor manera de determinar una buena conjetura 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 establecer manualmente el huso horario más tarde si nuestra mejor estimació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 de todos modos de todos modos, y nos ocupamos principalmente de los EE. UU. Independientemente.

He encontrado muchas bases de datos de códigos postales, y hasta ahora solo algunas contienen información de zonas horarias, pero las que sí lo hacen no son gratuitas, como esta . Si es absolutamente necesario abonar una suscripción a un servicio para hacerlo, no valdrá la pena y tendremos que preguntar a los usuarios de forma explícita.

Aunque el lenguaje no es particularmente relevante, ya que probablemente pueda convertir las cosas de la manera que sea necesaria, estamos usando PHP y MySQL.

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

    La mayoría de los estados están en exactamente un huso horario (aunque hay algunas excepciones). La mayoría de los códigos postales no cruzan los límites del estado (aunque hay algunas excepciones).

    Puede crear rápidamente su propia lista de zonas horarias por archivo comprimido 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 usando este enlace , o Google Earth, para asignar cremalleras a las zonas horarias para los estados que están divididos por una línea de zona horaria.

    La mayoría de los países que no son de los EE. UU. Con los que está tratando probablemente se encuentren exactamente en una zona horaria. Es posible que desee ver de dónde provienen los visitantes que provienen de la parte superior N de los EE. UU. Y solo buscar su zona horaria.

    Creé una tabla de base de datos MySQL de código abierto (con licencia MIT) que hace una referencia cruzada de códigos postales y zonas horarias y la subí a sourceforge.net:

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

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

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

    Si lo desea, también puede hacerse una idea de la zona horaria preguntando al navegador Josh Fraser que tiene un buen escrito 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); 

    Lo segundo que debe saber es si la ubicación observa el horario de verano (DST) o no. Como el horario de verano se observa siempre durante el verano, podemos comparar la compensación de tiempo entre dos fechas en enero, con el tiempo compensado entre dos fechas en junio. Si los desplazamientos son diferentes, entonces sabemos que la ubicación observa el horario de verano. Si los desplazamientos son los mismos, entonces sabemos que la ubicación NO observa 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 crédito por esto va a Josh Fraser.

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

    Aquí hay un SO preguntas que se refieren a obtener la zona horaria de javascript

    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&timestamp=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. A partir de la respuesta devuelta, parece que timeZoneName tiene en cuenta los ahorros de luz diurna, en función de la marca de tiempo, mientras que timeZoneId es un nombre independiente de DST para la zona horaria.

    Para mi uso, en Python, solo estoy pasando timestamp=0 y utilizando el valor timeZoneId para obtener un objeto tz_info de pytz , puedo usarlo para localizar cualquier fecha y hora particular en mi propio código.

    Creo que para PHP también puedes encontrar “America / New_York” en http://pecl.php.net/package/timezonedb

    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 simplemente no se ajustan perfectamente a las zonas horarias.

    Hace poco hice un hash Ruby de todos los códigos postales en los EE. UU. Y sus zonas horarias asociadas que podría usar si le interesa. Debería ser bastante fácil realizar ingeniería inversa para sus propósitos.

    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

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

    o

    2b) use una base de datos como la enlazada arriba por @Doug.

    De esta manera, puede encontrarlo a bajo costo (¡y con mucha precisión!) Para la mayoría de sus usuarios y luego utilizar uno de los otros métodos más caros para obtenerlo para el rest de los estados.

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

    También tenga en cuenta que si usa el servicio de geoencoding de Yahoo, puede tener la información de la zona horaria devuelta estableciendo el indicador correcto.

    http://developer.yahoo.com/geo/placefinder/guide/requests.html#flags-parameter

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

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

    PS No puede insertar todos los enlaces 🙁 Por lo tanto, use la búsqueda.

    En realidad, hay una gran API de Google para esto. Toma una ubicación y devuelve la zona horaria de esa ubicación. Debe ser lo suficientemente simple como para crear una secuencia de comandos bash o python para obtener los resultados de cada dirección en un archivo CSV o base de datos luego guarde la información de la zona horaria.

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

    Punto final de la solicitud:

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

    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 los husos horarios acortados, puede ejecutar este:

     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... 

    Mantengo una API de código postal a zona horaria llamada Zipgenius que utiliza los datos proporcionados por @chriv proporcionados anteriormente. Siéntase libre de usarlo para sus propias necesidades.