20

を使用するpytzと、次のようなタイムゾーンのリストを取得できます。

>>> from pytz import country_timezones
>>> print(' '.join(country_timezones('ch')))
Europe/Zurich
>>> print(' '.join(country_timezones('CH')))
Europe/Zurich

ユーザーから Country フィールドと City フィールドの両方を取得している場合、都市のタイムゾーンを決定するにはどうすればよいでしょうか?

4

7 に答える 7

28

pytzIANA タイム ゾーン データベース (オルソン データベース) のラッパーです。世界の任意の都市をその都市のタイムゾーンにマッピングするためのデータは含まれていません。

geopyさまざまな Web サービスを使用して、場所 (都市名など) を座標 (緯度、経度) に変換できるジオコーダーが必要になる場合があります。

from geopy import geocoders # pip install geopy

g = geocoders.GoogleV3()
place, (lat, lng) = g.geocode('Singapore')
# -> (u'Singapore', (1.352083, 103.819836))

都市の緯度、経度が与えられた場合、そのタイムゾーンは、efele.net/tz マップ/世界の TZ タイムゾーンのシェープファイルである tz_worldを使用して見つけることができます。たとえば、postgis timezone dbまたはpytzwhere:

import tzwhere

w = tzwhere()
print w.tzNameAt(1.352083, 103.819836)
# -> Asia/Singapore

askgeogeonamesなど、(緯度、経度) をタイムゾーンに変換できる Web サービスもあります。緯度経度からのタイムゾーン検索を参照してください。

コメントで@dashesyが指摘したように、タイムgeopyゾーンも見つけることができます(1.2以降):

timezone = g.timezone((lat, lng)) # return pytz timezone object
# -> <DstTzInfo 'Asia/Singapore' LMT+6:55:00 STD>

GeoNames は、都市のタイムゾーンを名前から直接取得できるオフライン データも提供します。

#!/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
于 2013-05-13T09:41:36.373 に答える
2

探している都市のタイムゾーン データベースを手動で検索する必要があると思います。

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)

(これは簡単な解決策です。たとえば、タイムゾーンの都市部分のみを一致させようとはしません。 を検索してみてくださいEurope。部分文字列の一致を行い、大文字と小文字を区別しないなどの検索を行いません。)

于 2013-05-12T09:51:31.800 に答える
1

requestsJSONを使用して解析するいくつかのGoogle API呼び出しでこれを解決することになりました。使用制限に達することは決してないので、API キーなしでそれを行うことができました。

https://gist.github.com/willcharlton/b055885e249a902402fc

これが役立つことを願っています。

于 2015-09-28T15:10:10.393 に答える