从Python / Django获取城市时区 [英] Get Timezone from City in Python/Django

查看:944
本文介绍了从Python / Django获取城市时区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 pytz ,我可以得到如下这样的时区列表:

 >>>来自pytz import country_timezones 
>>>> print(''.join(country_timezones('ch')))
欧洲/苏黎世
>>> print(''.join(country_timezones('CH')))
欧洲/苏黎世

鉴于我从用户那里获得了国家和城市字段,我可以如何确定城市的时区?

解决方案

p> pytz 是IA​​NA时区数据库(Olson数据库)的包装。它不包含将世界上任意城市映射到其所在时区的数据。



您可能需要一个地理编码器,例如 geopy 可以将一个地方(例如城市名称)翻译成其坐标(纬度,经度)使用各种网络服务:

 从geopy import geocoders#pip install geopy 

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

鉴于城市的纬度,经度,有可能使用 tz_world,efele.net/tz地图/ TZ时区的shapefile查找其时区世界,例如,通过 postgis timezone db pytzwhere

  import tzwhere 

w = tzwhere()
print w.tzNameAt(1.352083,103.819836)
# - >亚洲/新加坡

还有允许将(纬度,经度)转换为时区的Web服务例如, askgeo geonames ,请参阅从纬度经度的时区查询。 p>

作为 @dashesy在评论中指出 geopy 也可以找到时区(自1.2):

  timezone = g.timezone((lat,lng))#return pytz timezone object 
# - > < DstTzInfo'亚洲/新加坡'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
从zipfile import ZipFile

import pytz#pip install pytz

geonames_url ='http://download.geonames.org/export/dump/'
basename ='cities15000'#所有拥有人口的城市> 15000或资本
filename = basename +'.zip'

#获取文件
如果不是os.path.exists(filename):
urlretrieve(urljoin(geonames_url ,filename),filename)

#parse it
city2tz = defaultdict(set)
with ZipFile(filename)as zf,zf.open(basename +'.txt')作为文件:
文件中的行:
fields = line.split(b'\t')
如果字段:#geoname表http://download.geonames.org/export / dump /
name,asciiname,alternatenames = fields [1:4]
timezone = fields [-2] .decode('utf-8')。strip()
if timezone:
在[name,asciiname] + alternatenames.split(b',')中的城市
city = city.decode('utf-8')。strip()
如果城市:
city2tz [city] .add(timezone)

print(可用城市名称数量(含别名):%d%len(city2tz))


n = sum((len(timezones)> 1)对于城市,timezones在city2tz.iteritems())
print()
print(查找不祥的城市名称的数量\
(有多个关联时区):%d%n)


fmt ='%Y-%m-%d%H:%M:%S%Z%z'
city =Zurich
在城市2z中的tzname [城市]:
now = datetime.now(pytz.timezone(tzname))
print()
print( %s在%s时区%(city,tzname))
print(当前时间%s是%s%(city,now.strftime(fmt)))



输出



 可用城市名称(含别名):112682 

查找不确定城市名称
(有多个关联时区):2318

苏黎世在欧洲/苏黎世时区
苏黎世当前时间是2013-05-13 11:36:33 CEST + 0200


Using pytz, I am able to get a list of timezones like so:

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

Given that I am getting both Country and City fields from the user, how can I go about determining the timezone for the city?

解决方案

pytz is a wrapper around IANA Time Zone Database (Olson database). It does not contain data to map an arbitrary city in the world to the timezone it is in.

You might need a geocoder such as geopy that can translate a place (e.g., a city name) to its coordinates (latitude, longitude) using various web-services:

from geopy import geocoders # pip install geopy

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

Given city's latitude, longitude, it is possible to find its timezone using tz_world, an efele.net/tz map / a shapefile of the TZ timezones of the world e.g., via postgis timezone db or pytzwhere:

import tzwhere

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

There are also web-services that allow to convert (latitude, longitude) into a timezone e.g., askgeo, geonames, see Timezone lookup from latitude longitude.

As @dashesy pointed out in the comment, geopy also can find timezone (since 1.2):

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

GeoNames also provides offline data that allows to get city's timezone directly from its name e.g.:

#!/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)))

Output

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

这篇关于从Python / Django获取城市时区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆