Сопоставление почтового индекса США с часовым поясом

Когда пользователи регистрируются в нашем приложении, мы можем вывести их почтовый индекс, когда сверяем их с национальной базой данных. Каков наилучший способ определить хорошее потенциальное предположение об их часовом поясе по этому почтовому индексу?

Мы пытаемся свести к минимуму объем данных, которые мы явно должны запрашивать у них. Они смогут вручную установить часовой пояс позже, если наше предположение окажется неверным. Я понимаю, что почтовые индексы не помогут определить часовой пояс за пределами США, но в этом случае нам все равно придется запрашивать вручную, и мы все равно имеем дело преимущественно с США.

Я нашел много баз данных почтовых индексов, и пока только некоторые из них содержат информацию о часовых поясах, но те, которые есть, не бесплатны, например вот этот. Если для этого абсолютно необходимо оплатить подписку на услугу, то это того не стоит, и нам просто нужно будет явно попросить пользователей.

Хотя язык не имеет особого значения, так как я, вероятно, могу преобразовать что угодно, но мы используем PHP и MySQL.


person Doug Kavendek    schedule 16.03.2010    source источник
comment
+1 за вопрос об угадывании   -  person Chris McCall    schedule 16.03.2010


Ответы (12)


Я только что нашел бесплатную базу данных в формате zip, которая включает в себя смещение времени и участие в переходе на летнее время. Мне нравится ответ Эрика Дж., так как он помог бы мне выбрать фактический часовой пояс, а не просто смещение (потому что никогда нельзя быть полностью уверенным в правилах), но я думаю, что могу начать с этого и попытаться найти лучшее совпадение часового пояса на основе конфигурации смещения/летнего времени. Я думаю, что могу попытаться настроить простую версию ответа Development 4.0, чтобы проверить, что я получаю из zip-информации, в качестве теста на работоспособность. Это определенно не так просто, как я надеюсь, но комбинация должна дать мне по крайней мере 90% уверенности в часовом поясе пользователя.

person Doug Kavendek    schedule 16.03.2010
comment
@Doug: Все, что связано с геокодированием, никогда не будет правильным на 100%, тем более, что вы действуете только на уровне ZIP. Тем не менее, если вы сможете быть правы более чем в 90% случаев, это, вероятно, принесет пользу вашим пользователям. Худшее, что вы, вероятно, будете свободны, это один час. - person Eric J.; 16.03.2010
comment
будьте осторожны, бесплатные базы данных zip почти всегда устарели, поскольку почтовая служба ежемесячно меняет этот файл. см. также semaphorecorp.com/cgi/zip5.html - person joe snyder; 25.06.2010
comment
Эта ссылка поднимает некоторые хорошие моменты, но, поскольку я просто использую ее, чтобы сделать предположение об общей области (и допуская исправления), мне не о чем слишком беспокоиться. Если почтовый индекс не может охватывать несколько часовых поясов, но в этом случае это уже пограничный случай, и, поскольку мы никогда не будем запрашивать адреса пользователей, мы не сможем использовать их для дальнейшей проверки. Но на самом деле, нам, вероятно, было бы полезно подписаться на один из них, прежде чем что-то выйдет в эфир, чтобы быть в курсе последних событий. Бесплатная по крайней мере хороша для тестирования. - person Doug Kavendek; 25.06.2010
comment
@joesnyder Ссылка не работает, не могли бы вы обновить или хотя бы объяснить, что там было? - person dlsso; 29.03.2019
comment
@joesnyder Как мы можем получать изменения из почтовой службы в режиме реального времени, или ежемесячно в пакетном режиме, или просто программно загружать из них весь текущий набор данных? - person billy; 02.10.2020
comment
@billy Перейдите на https://www.usps.com/business/web-tools-apis/ - person joe snyder; 03.10.2020
comment
Ссылки ZIP снова переехали. Перейдите на страницу https://sites.google.com/site/masteraddressfile/zp4/zip5 и https://sites.google.com/site/masteraddressfile/misc/oldzips - person joe snyder; 03.10.2020

Большинство штатов находятся ровно в одном часовом поясе (хотя есть несколько исключений). Большинство почтовых индексов не пересекают границы штатов (хотя есть несколько исключений).

Вы можете быстро составить собственный список часовых поясов для каждого почтового индекса, объединив эти факты.

Вот список диапазонов почтовых индексов для каждого штата и список состояния по часовому поясу.

Вы можете увидеть границы почтовых индексов и сравнить их с картой часовых поясов, используя эту ссылку или Google Земля, чтобы сопоставить почтовые индексы с часовыми поясами для штатов, разделенных линией часового пояса.

Большинство неамериканских стран, с которыми вы имеете дело, вероятно, находятся ровно в одном часовом поясе (опять же, есть исключения). В зависимости от ваших потребностей вы можете посмотреть, откуда приходят ваши первые N посетителей из-за пределов США, и просто посмотреть их часовой пояс.

person Eric J.    schedule 16.03.2010
comment
Ого, а какие исключения? - person Hamish Grubijan; 16.03.2010
comment
@Hamish: Исключения для штатов в нескольких часовых поясах вы можете увидеть по ссылке в Википедии (штаты для каждого часового пояса). Пока мы разговариваем, мой коллега сопоставляет ZIP-файлы со штатами и наткнулся на несколько ZIP-архивов, которые пересекают границы штатов. Например, 42223. - person Eric J.; 16.03.2010
comment
Насколько я знаю, Монтана, Орегон, Айдахо, Дакота, Небраска, Канзас, Техас и некоторые средневосточные штаты. - person dassouki; 16.03.2010
comment
Также обратите внимание, что в некоторых штатах (только Аризона и Гавайи, я думаю) не соблюдается переход на летнее время. - person Jon-Eric; 16.03.2010
comment
Штаты на северо-западе США имеют миллион и один почтовый индекс на штат; честное предупреждение. - person Qix - MONICA WAS MISTREATED; 30.03.2013
comment
@ Джон-Эрик: Есть также некоторые округа на Среднем Западе, которые не соблюдают переход на летнее время, хотя в штате, в котором они находятся, это происходит. - person Eric J.; 31.03.2013
comment
Эта идея о том, что большинство штатов имеют только один часовой пояс, или большинство стран имеют только один часовой пояс, равносильна утверждению, что мне нужна только большая часть моего клиенты, чтобы быть счастливыми. По крайней мере, дважды в моей жизни я переезжал на новый почтовый индекс, которого не было в некоторых базах данных, что усложняло ситуацию, чем вы думаете. Есть гораздо больше действительно веских причин не определять часовой пояс по почтовому индексу. Я перечислил некоторые из них здесь. - person Matt Johnson-Pint; 09.05.2013
comment
@MattJohnson: Да, новые почтовые индексы добавляются достаточно часто, а старые почтовые индексы переопределяются (часто разделяются). Кроме того, область, определяемая почтовым индексом, даже не обязательно должна быть полностью соединена. Почтовый индекс, в котором я вырос, разбит на несколько частей, похожих на острова, окруженные другими почтовыми индексами. Они не являются отличными индикаторами каких-либо границ, кроме границ ZIP. Они пересекают часовые пояса, границы города, границы округов и, по крайней мере, в одном случае пересекают границу штата. - person Eric J.; 09.05.2013
comment
Это намного больше, чем несколько исключений. timetemperature.com/tzus/indiana_time_zone.shtml - person Chris Moschini; 19.08.2014

Я создал таблицу базы данных MySQL с открытым исходным кодом (под лицензией MIT), которая содержит перекрестные ссылки на почтовые индексы и часовые пояса, и загрузил ее на sourceforge.net:

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

Он получен из четырех мест (основной API Yahoo PlaceFinder - спасибо @Chris N)

Дополнительную информацию и инструкции см. в файле README.

person chriv    schedule 24.04.2012
comment
Есть ли шанс, что у вас все еще есть код, который это сгенерировал? Ему уже несколько лет, и я надеюсь получить свежий набор данных. - person billy; 02.10.2020

Если вы хотите, вы также можете получить представление о часовом поясе, запросив у браузера Джоша Фрейзера хорошая запись здесь

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

Второе, что вам нужно знать, это соблюдает ли местоположение летнее время (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
}

Вся заслуга в этом принадлежит Джошу Фрейзеру.

Это может помочь вам с клиентами за пределами США и может дополнить ваш почтовый подход.

Вот вопросы SO, которые касаются получения часового пояса из javascript

person Development 4.0    schedule 16.03.2010
comment
Благодарность! Как упоминает Джош на своем сайте, Джон Нюландер написал более надежное решение. Вместо этого используйте его версию. Его версия находится здесь: bitbucket.org/pellepim/jstimezonedetect - person Brad Parks; 20.06.2012

У Google есть специальный API для этого: https://developers.google.com/maps/documentation/timezone/

например: 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"
}

Им требуется временная метка unix в строке запроса. Из возвращенного ответа видно, что timeZoneName учитывает переход на летнее время на основе метки времени, а timeZoneId — это имя часового пояса, не зависящее от перехода на летнее время.

Для моего использования в Python я просто передаю timestamp=0 и использую значение timeZoneId для получения объекта tz_info из pytz, я могу затем использовать это для локализации любого конкретного даты и времени в моем собственном коде.

Я считаю, что для PHP аналогичным образом вы можете найти «Америка/Нью-Йорк» в http://pecl.php.net/package/timezonedb

person Anentropic    schedule 01.09.2014
comment
Обратите внимание, что лицензия на API геокодирования Google требует, чтобы вы использовали результаты для отображения на карте... - person Josh; 03.09.2015
comment
@Josh Вы говорите, что я не могу использовать API геокодирования для определения местоположения в целях определения часового пояса в этом месте? - person Cruncher; 03.12.2018
comment
На странице политики: вы можете отображать результаты API часовых поясов на карте Google или без карты. Если вы хотите отобразить результаты API часовых поясов на карте, эти результаты должны отображаться на карте Google. Запрещено использовать данные API часовых поясов на карте, отличной от карты Google. developers.google.com/maps/documentation/timezone/policies - person tmorell; 10.07.2019

Ruby gem для преобразования почтового индекса в часовой пояс: https://github.com/Katlean/TZip (форк от https://github.com/farski/TZip).

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

Он быстрый, маленький и не имеет внешних зависимостей, но имейте в виду, что почтовые индексы просто не соответствуют часовым поясам.

person mkirk    schedule 16.05.2012
comment
И оригинальный TZip, и вилка Katlean хороши, но не на 100% точны. Некоторые почтовые индексы (вероятно, введенные в последние несколько лет) не учитываются. - person bigtex777; 22.01.2016
comment
Ссылка на вилку мертва, а оригинал не обновлялся 8 лет, так что это, вероятно, не лучший выбор. - person Casey; 14.01.2021

Я работал над этой проблемой для своего собственного сайта и чувствую, что нашел довольно хорошее решение.

1) Назначить часовые пояса всем штатам только с одним часовым поясом (большинство штатов)

а потом либо

2a) используйте решение js (Javascript/PHP и часовые пояса) для остальных состояний

or

2b) используйте базу данных, подобную той, на которую ссылается @Doug выше.

Таким образом, вы можете дешево (и очень точно!) найти tz для большинства ваших пользователей, а затем использовать один из других, более дорогих методов, чтобы получить его для остальных штатов.

Не супер элегантно, но мне показалось лучше, чем использование js или базы данных для каждого пользователя.

person Matt Parrilla    schedule 04.07.2011

В дополнение к ответу Дуга Кавендека. Можно использовать следующий подход, чтобы приблизиться к tz_database.

  1. Скачать [Бесплатную базу данных широты и долготы почтового индекса]
  2. Скачать [Шейп-файл часовых поясов TZ мира]
  3. Используйте любую бесплатную библиотеку для запросов к шейп-файлам (например, .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];

P.S. Все ссылки не вставишь :( Так что пользуйся поиском.

person Dmitriy Zubrilin    schedule 26.09.2014

Это загрузит файл yaml, который сопоставит все часовые пояса с массивом их почтовых индексов:

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

e.g.

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

Если вы предпочитаете сокращенные часовые пояса, вы можете запустить это:

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

e.g.

"EDT" => ["00100", "00101", "00102", "00103", "00104", ...]
"CDT" => ["35000", "35001", "35002", "35003", "35004", ...]
etc...
person BananaNeil    schedule 08.06.2015
comment
Сюда входит 96941 (Микронезия) по тихоокеанскому времени и 83500 как почтовый индекс по тихоокеанскому времени, но я не верю, что он существует в Соединенных Штатах. Как были созданы данные? - person Justin Blank; 02.09.2016


Также обратите внимание, что если вы используете службу геокодирования Yahoo, вы можете получить информацию о часовом поясе, установив правильный флаг.

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

person Chris N    schedule 19.10.2011
comment
Возможно, когда-то он был полезен, но отличный сервис геокодирования Yahoo был закрыт несколько лет назад. - person lreeder; 04.03.2019

На самом деле для этого есть отличный Google API. Он принимает местоположение и возвращает часовой пояс для этого местоположения. Должно быть достаточно просто создать сценарий bash или python, чтобы получить результаты для каждого адреса в файле CSV или базе данных, а затем сохранить информацию о часовом поясе.

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

Конечная точка запроса:

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

Ответ:

{
   "dstOffset" : 3600,
   "rawOffset" : -18000,
   "status" : "OK",
   "timeZoneId" : "America/New_York",
   "timeZoneName" : "Eastern Daylight Time"
}
person Anonmily    schedule 12.06.2016
comment
следует отметить, что API стоит 5 долларов за 1 тыс. звонков. - person FlyingZebra1; 02.05.2020