Thi*_*elo 17
我知道,这是一种作弊行为,但是'/etc/localtime'
起作用对你不起作用?如下:
>>> import os
>>> '/'.join(os.readlink('/etc/localtime').split('/')[-2:])
'Australia/Sydney'
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你.
编辑:我喜欢@ AH的想法,万一 '/etc/localtime'
不是符号链接.将其翻译成Python:
#!/usr/bin/env python
from hashlib import sha224
import os
def get_current_olsonname():
tzfile = open('/etc/localtime')
tzfile_digest = sha224(tzfile.read()).hexdigest()
tzfile.close()
for root, dirs, filenames in os.walk("/usr/share/zoneinfo/"):
for filename in filenames:
fullname = os.path.join(root, filename)
f = open(fullname)
digest = sha224(f.read()).hexdigest()
if digest == tzfile_digest:
return '/'.join((fullname.split('/'))[-2:])
f.close()
return None
if __name__ == '__main__':
print get_current_olsonname()
Run Code Online (Sandbox Code Playgroud)
Anu*_*yal 17
我认为最好的办法是去通所有pytz时区和检查哪一个相匹配的本地时区,每个pytz时区对象包含有关UTCOFFSET和TZNAME像CDT,EST信息,可以从以下地址获得有关本地时间相同的信息time.timezone/altzone
和time.tzname
,我认为这是足以正确匹配pytz数据库中的本地时区,例如
import time
import pytz
import datetime
local_names = []
if time.daylight:
local_offset = time.altzone
localtz = time.tzname[1]
else:
local_offset = time.timezone
localtz = time.tzname[0]
local_offset = datetime.timedelta(seconds=-local_offset)
for name in pytz.all_timezones:
timezone = pytz.timezone(name)
if not hasattr(timezone, '_tzinfos'):
continue#skip, if some timezone doesn't have info
# go thru tzinfo and see if short name like EDT and offset matches
for (utcoffset, daylight, tzname), _ in timezone._tzinfos.iteritems():
if utcoffset == local_offset and tzname == localtz:
local_names.append(name)
print local_names
Run Code Online (Sandbox Code Playgroud)
输出:
['America/Atikokan','America/Bahia_Banderas','America/Bahia_Banderas','America/Belize','America/Cambridge_Bay','America/Cancun','America/Chicago','America/Chihuahua',' America/Coral_Harbour','America/Costa_Rica','America/El_Salvador','America/Fort_Wayne','America/Guatemala','America/Indiana/Indianapolis','America/Indiana/Knox','America/Indiana/Marengo','America/Indiana/Marengo','America/Indiana/Petersburg','America/Indiana/Tell_City','America/Indiana/Vevay','America/Indiana/Vincennes','America/Indiana/Winamac' ,'America/Indianapolis','America/Iqaluit','America/Kentucky/Louisville','America/Kentucky/Louisville','America/Kentucky/Monticello','America/Knox_IN','America/Louisville',' America/Louisville','America/Managua','America/Matamoros','America/Menominee','America/Merida','America/Mexico_City','America/Monterrey','America/North_Dakota/Beulah',' America/North_Dakota/Center','America/North_Dakota/New_Salem','America/Ojinaga','America/Pangnirtung','Am erica/Rainy_River','America/Rankin_Inlet','America/Resolute','America/Resolute','America/Tegucigalpa','America/Winnipeg','CST6CDT','Canada/Central','Mexico/General' ,'US/Central','US/East-Indiana','US/Indiana-Starke']
在生产中,您可以预先创建这样的映射并保存它而不是总是迭代.
更改时区后测试脚本:
$ export TZ ='澳大利亚/悉尼'
$ python get_tz_names.py
['Antarctica/Macquarie','Australia/ACT','Australia/Brisbane','Australia/Canberra','Australia/Currie','Australia/Hobart' ,'Australia/Lindeman','Australia/Melbourne','Australia/NSW','Australia/Queensland','Australia/Sydney','Australia/Tasmania','Australia/Victoria']
Til*_*ilo 13
一个问题是有多个"漂亮的名字",如"澳大利亚/悉尼",它指向同一时区(例如CST).
因此,您需要获取本地时区的所有可能名称,然后选择您喜欢的名称.
例如:对于澳大利亚,有5个时区,但更多的时区标识符:
"Australia/Lord_Howe", "Australia/Hobart", "Australia/Currie",
"Australia/Melbourne", "Australia/Sydney", "Australia/Broken_Hill",
"Australia/Brisbane", "Australia/Lindeman", "Australia/Adelaide",
"Australia/Darwin", "Australia/Perth", "Australia/Eucla"
Run Code Online (Sandbox Code Playgroud)
你应该检查是否有一个包装TZinfo的库来处理时区API.
例如:对于Python,检查pytz
库:
和
http://pypi.python.org/pypi/pytz/
在Python中你可以做到:
from pytz import timezone
import pytz
In [56]: pytz.country_timezones('AU')
Out[56]:
[u'Australia/Lord_Howe',
u'Australia/Hobart',
u'Australia/Currie',
u'Australia/Melbourne',
u'Australia/Sydney',
u'Australia/Broken_Hill',
u'Australia/Brisbane',
u'Australia/Lindeman',
u'Australia/Adelaide',
u'Australia/Darwin',
u'Australia/Perth',
u'Australia/Eucla']
Run Code Online (Sandbox Code Playgroud)
但是Python的API似乎非常有限,例如它似乎没有像Ruby这样的调用all_linked_zone_names
- 它可以找到给定时区的所有同义词名称.
如果/etc/localtime
你可以评估,那么下面的技巧可能会有用 - 在将它翻译成python之后:
> md5sum /etc/localtime
abcdefabcdefabcdefabcdefabcdefab /etc/localtime
> find /usr/share/zoneinfo -type f |xargs md5sum | grep abcdefabcdefabcdefabcdefabcdefab
abcdefabcdefabcdefabcdefabcdefab /usr/share/zoneinfo/Europe/London
abcdefabcdefabcdefabcdefabcdefab /usr/share/zoneinfo/posix/Europe/London
...
Run Code Online (Sandbox Code Playgroud)
只使用官方地区名称"欧洲","美国"过滤重复项...如果仍有重复项,您可以使用最短的名称:-)
import pytz
import time
#import locale
import urllib2
yourOlsonTZ = None
#yourCountryCode = locale.getdefaultlocale()[0].split('_')[1]
yourCountryCode = urllib2.urlopen('http://api.hostip.info/country.php').read()
for olsonTZ in [pytz.timezone(olsonTZ) for olsonTZ in pytz.all_timezones]:
if (olsonTZ._tzname in time.tzname) and (str(olsonTZ) in pytz.country_timezones[yourCountryCode]):
yourOlsonTZ = olsonTZ
break
print yourOlsonTZ
Run Code Online (Sandbox Code Playgroud)
根据您的时区名称(根据Python的time
模块)和您的国家代码(根据Python的,hostip.info项目,它引用您的IP地址和地理位置),此代码将根据您的Olson Timezone进行最佳猜测.你呢).locale
模块
例如,简单地匹配Timzone名称可能导致America/Moncton
,America/Montreal
或America/New_York
对EST(GMT-5).但是,如果你的国家是美国,它将限制答案America/New_York
.
但是,如果您所在的国家/地区是加拿大,则该脚本将默认为加拿大最顶级的结果(America/Moncton
).如果有办法进一步完善这一点,请随时在评论中留下建议.