从经纬度获取时区?

35

我正在尝试获取经纬度坐标的时区,但遇到了一些问题。错误可能非常基础。

我有一个数据库中约有600行的表格。每一行都包含世界某个地方的经纬度坐标。我想将这些坐标输入到一个函数中,然后检索出对应的时区。目的是将这600个地方中每个地方的本地时间戳转换为UTC时间。

我发现博客文章使用一段代码从地理坐标中获取时区。

当我尝试运行代码时,出现错误geonames未定义。我已经申请了geonames账户。

我认为我只是在错误的目录中保存了函数文件或者犯了一些简单的错误。有人能帮忙吗?

#-------------------------------------------------------------------------------
# Converts latitude longitude into a time zone
# REF: https://gist.github.com/pamelafox/2288222
# REF: http://blog.pamelafox.org/2012/04/converting-addresses-to-timezones-in.html
#-------------------------------------------------------------------------------

geonames_client = geonames.GeonamesClient('Username_alpha')
geonames_result = geonames_client.find_timezone({'lat': 48.871236, 'lng': 2.77928})
user.timezone = geonames_result['timezoneId']

5
您似乎没有导入 geonames。添加一行import geonames吗? - Martijn Pieters
4个回答

40

使用tzwhere和pytz:

import datetime
import pytz
from tzwhere import tzwhere

tzwhere = tzwhere.tzwhere()
timezone_str = tzwhere.tzNameAt(37.3880961, -5.9823299) # Seville coordinates
timezone_str
#> Europe/Madrid

timezone = pytz.timezone(timezone_str)
dt = datetime.datetime.now()
timezone.utcoffset(dt)
#> datetime.timedelta(0, 7200)

1
它作为我们需要的离线解决方案运行良好。虽然有些人可能会遇到错误:在导入tzwhere时,OSError:找不到lib geos_c或加载其任何变体。这个链接可以帮助解决问题:https://dev59.com/gmIj5IYBdhLWcg3w8JRZ#23057508 - sunsetjunks
在 Mac OS X Sierra 和 Python 2.7 中不起作用。 - Ciasto piekarz
1
有任何额外的细节吗?错误信息?您可以尝试使用Python 3吗? - tuxayo
1
调用 tzNameAt 方法时,如果没有错误,则返回 None - Ciasto piekarz
非常奇怪:对我来说,第一次运行正常,但如果再次调用tzwhere.tzwhere(),我会得到AttributeError:'tzwhere'对象没有属性'tzwhere'。 - kolergy
显示剩余4条评论

24

我能够使用timezonefinder进行适合我的目的的查找:

import datetime
import timezonefinder, pytz

tf = timezonefinder.TimezoneFinder()

# From the lat/long, get the tz-database-style time zone name (e.g. 'America/Vancouver') or None
timezone_str = tf.certain_timezone_at(lat=49.2827, lng=-123.1207)

if timezone_str is None:
    print("Could not determine the time zone")
else:
    # Display the current time in that time zone
    timezone = pytz.timezone(timezone_str)
    dt = datetime.datetime.utcnow()
    print("The time in %s is %s" % (timezone_str, dt + timezone.utcoffset(dt)))

在从timezonefinder的pypi页面链接的文档中,讨论了timezonefinder的方法及其限制。

timezonefinderpytz可以在同名的pip软件包中找到。


2
我还没有对多个输入坐标进行全面测试,因此无法确定准确性,但就速度而言,timezonefinder比tzwhere快得多。至少对我来说是这样。 - Jim Carr
这是目前最新的答案,但为了后人,真的值得查看这个链接,因为它经常更新:https://dev59.com/UGQo5IYBdhLWcg3wZepg - stephan

6

这个可以正常工作:

import geonames
geonames_client = geonames.GeonamesClient('demo')
geonames_result = geonames_client.find_timezone({'lat': 48.871236, 'lng': 2.77928})
print geonames_result['timezoneId']

输出:

'Europe/Paris'

@manuel_riel 这是哪个库...import geonames? - sirvon
1
这只是一个包装geonames.org的Python软件包。它在Pypi上 https://pypi.python.org/pypi/geonames/ - Manu
你链接的包似乎没有GeonamesClient类。你可能在使用不同的包吗? - waterproof
4
这个回答不再有效。 - Jwely
1
提到的库在Linux下无法工作。该代码仅支持Python2,并且存在硬编码的Windows路径。 - maxbit89

1
import requests
lat = 48.871236 ## your latitude
lon = 2.77928 ## your longitude

url = "http://api.geonames.org/timezoneJSON?formatted=true&lat={}&lng={}&username=demo".format(lat,lon)

r = requests.get(url) ## Make a request
return r.json()['timezoneId'] ## return the timezone

1
它运行得很好。但是,使用此Web服务是否有任何命中限制? - Diansheng
1
这是我收到的内容:{'status': {'message': '演示版每日20000个信用额度已超过限制。请使用特定于应用程序的帐户。不要将演示帐户用于您的应用程序。', 'value': 18}} :) - VivienG
使用Python 3.8,我遇到了“KeyError: 'timezoneId'”错误。 - duff18

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接