#!/usr/bin/env python
import os
from collections import defaultdict
from datetime import datetime
from urllib import urlretrieve
from urlparse import urljoin
from zipfile import ZipFile
import pytz # pip install pytz
geonames_url = 'http://download.geonames.org/export/dump/'
basename = 'cities15000' # all cities with a population > 15000 or capitals
filename = basename + '.zip'
# get file
if not os.path.exists(filename):
urlretrieve(urljoin(geonames_url, filename), filename)
# parse it
city2tz = defaultdict(set)
with ZipFile(filename) as zf, zf.open(basename + '.txt') as file:
for line in file:
fields = line.split(b'\t')
if fields: # geoname table http://download.geonames.org/export/dump/
name, asciiname, alternatenames = fields[1:4]
timezone = fields[-2].decode('utf-8').strip()
if timezone:
for city in [name, asciiname] + alternatenames.split(b','):
city = city.decode('utf-8').strip()
if city:
city2tz[city].add(timezone)
print("Number of available city names (with aliases): %d" % len(city2tz))
#
n = sum((len(timezones) > 1) for city, timezones in city2tz.iteritems())
print("")
print("Find number of ambigious city names\n "
"(that have more than one associated timezone): %d" % n)
#
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
city = "Zurich"
for tzname in city2tz[city]:
now = datetime.now(pytz.timezone(tzname))
print("")
print("%s is in %s timezone" % (city, tzname))
print("Current time in %s is %s" % (city, now.strftime(fmt)))
输出
Number of available city names (with aliases): 112682
Find number of ambigious city names
(that have more than one associated timezone): 2318
Zurich is in Europe/Zurich timezone
Current time in Zurich is 2013-05-13 11:36:33 CEST+0200
from pytz import country_timezones, timezone
def find_city(query):
for country, cities in country_timezones.items():
for city in cities:
if query in city:
yield timezone(city)
for tz in find_city('Zurich'):
print(tz)
这里提出了很多可能的解决方案,设置起来都有点乏味。
为了让下一个遇到这个问题的人更快地处理问题,我从Will Charlton那里取了一个,并用它制作了一个快速的python库:https://pypi.python.org/pypi/whenareyou
让你
datetime.datetime(2002, 10, 27, 6, 0, tzinfo=<DstTzInfo 'Europe/Berlin' CET+1:00:00 STD>)
。这将获得一个pytz对象(在示例中为
tz
),以便您可以pythonicly使用它。pytz
是IANA时区数据库(Olson数据库)的包装器。它不包含将世界上任意一个城市映射到其所在时区的数据。您可能需要一个地理编码器,例如^{} ,它可以使用各种web服务将一个地方(例如,一个城市名)转换为其坐标(纬度、经度):
给定城市的纬度、经度,可以使用tz_world, an efele.net/tz map / a shapefile of the TZ timezones of the world来查找其时区,例如通过postgis timezone db或^{} :
还有一些web服务允许将(纬度、经度)转换为时区,例如askgeo,geonames,请参见Timezone lookup from latitude longitude。
作为@dashesy pointed out in the comment,
geopy
也可以找到时区(从1.2开始):GeoNames also provides offline data允许直接从城市名称中获取城市时区,例如:
输出
我认为您需要手动搜索时区数据库,查找您要查找的城市:
(这只是一个快速而肮脏的解决方案,例如,它不试图只匹配时区的城市部分-尝试搜索
Europe
,它进行子字符串匹配,不搜索不区分大小写等。)相关问题 更多 >
编程相关推荐