将美国邮政编码映射到时区

问题描述 投票:78回答:14

当用户在我们的应用程序中注册时,我们可以在我们针对国家数据库验证邮政编码时推断他们的邮政编码。从这个邮政编码确定他们的时区的潜在猜测的最佳方法是什么?

我们正在努力减少我们明确要求他们提供的数据量。如果我们的最佳猜测是错误的,他们将能够稍后手动设置时区。我发现邮政编码无助于搞清楚美国以外的时区,但在这种情况下我们不得不手动询问,而且无论如何我们主要与美国打交道。

我发现了很多邮政编码数据库,到目前为止只有少数包含时区信息,但那些不是免费的,例如this one。如果为了做到这一点而必须支付订阅服务,那么它就不值得了,我们只需要明确询问用户。

虽然语言不是特别相关,因为我可以转换所需的东西,但我们使用的是PHP和MySQL。

timezone zipcode
14个回答
37
投票

我刚刚发现了一个包括时间偏移和参与夏令时的free zip database。我喜欢Erik J的答案,因为它可以帮助我选择实际的时区而不是偏移(因为你永远不能完全确定规则),但我想我可能会从这开始,并尝试根据偏移/ dst配置找到最佳时区匹配。我想我可能会尝试设置一个简单版本的Development 4.0的答案来检查我从zip信息中得到的作为一个完整性测试。这绝对不是我希望的那么简单,但组合应该让我至少90%确定用户的时区。


1
投票

请参阅Olson数据库的以下链接:


1
投票

我维护一个名为ftp://ftp.iana.org/tz/releases的zipcode-to-timezone API,它使用上面提供的@chriv提供的数据。随意使用它以满足您的需求。


0
投票

另请注意,如果您碰巧使用Yahoo地理编码服务,则可以通过设置正确的标志来返回给您的时区信息。

ftp://elsie.nci.nih.gov/pub/


0
投票

这将下载一个yaml文件,该文件将所有时区映射到其zipcodes数组:

https://iana.org/time-zones

EG

Zipgenius

如果你更喜欢缩短的时区,你可以运行这个:

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

EG

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

0
投票

实际上有一个很棒的Google API。它接收一个位置并返回该位置的时区。应该足够简单,可以创建一个bash或python脚本来获取CSV文件或数据库中每个地址的结果,然后保存时区信息。

"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

响应:

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

24
投票

大多数州都在一个时区(尽管有一些例外)。大多数邮政编码不跨越州界(尽管有一些例外)。

您可以通过组合这些事实快速找出每个zip的时区列表。

这是zip code ranges per state列表和states per time zone列表。

您可以使用this link或Google地球查看邮政编码的边界并与时区地图进行比较,以将拉链映射到按时区线划分的州的时区。

您正在处理的大多数非美国国家可能只属于一个时区。您可能想要查看前N名非美国访客的来源,并查看他们的时区。


11
投票

我创建了一个开源(MIT许可)MySQL数据库表,交叉引用邮政编码和时区,并将其上传到sourceforge.net:

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

它来自四个地点(主要的Yahoo PlaceFinder API - 感谢@Chris N)

有关更多信息和说明,请参阅自述文件。


8
投票

如果你愿意,你也可以通过询问浏览器Josh Fraser有a nice write up on it here来了解时区。

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)。由于夏季期间始终遵守夏令时,我们可以将1月份两个日期之间的时间偏差与6月份两个日期之间的时间偏差进行比较。如果偏移量不同,那么我们知道该位置遵守DST。如果偏移量相同,那么我们知道该位置没有观察到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
}

所有这一切归功于Josh Fraser。

这可能会帮助您在美国以外的客户,它可能会补充您的zip方法。

Here is a SO questions that touch on getting the timezone from javascript


5
投票

Google有一个特定的API:https://developers.google.com/maps/documentation/timezone/

例如: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"
}

它们需要查询字符串上的unix时间戳。从返回的响应看来,timeZoneName考虑了基于时间戳的夏令时,而timeZoneId是时区的独立于DST的名称。

对于我的使用,在Python中,我只是传递timestamp=0并使用timeZoneId值从tz_info获取pytz对象,然后我可以使用它来本地化我自己的代码中的任何特定日期时间。

我相信PHP同样可以在http://pecl.php.net/package/timezonedb找到“America / New_York”


4
投票

Ruby gem将邮政编码转换为时区:https://github.com/Katlean/TZip(从https://github.com/farski/TZip分叉)。

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

它速度快,体积小,没有外部依赖性,但请记住,邮政编码并不能完美映射到时区。


2
投票

我最近made a Ruby hash of all the zipcodes in the US and their associated timezones你可以使用,如果你感兴趣。为了您的目的,应该很容易进行逆向工程。


1
投票

我一直在为自己的网站解决这个问题,感觉我已经找到了一个非常好的解决方案

1)将时区分配给只有一个时区的所有状态(大多数状态)

然后要么

2a)使用js解决方案(Javascript/PHP and timezones)用于剩余状态

要么

2b)使用像@Doug上面链接的数据库。

通过这种方式,您可以为大多数用户找到便宜(并且非常准确!)的tz,然后使用其他更昂贵的方法之一来获取其他州。

不是超级优雅,但对我来说似乎比为每个用户使用js或数据库更好。


1
投票

除了Doug Kavendek的回答。可以使用以下方法来接近tz_database。

  1. 下载[免费邮编纬度和经度数据库]
  2. 下载[世界TZ时区的形状文件]
  3. 使用任何免费库进行shapefile查询(例如.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];

附:无法插入所有链接:(所以请使用搜索。

© www.soinside.com 2019 - 2024. All rights reserved.