Python 在我看来,这个算法和Anurag Uniyal提出的解决方案(只保留两种方法返回的可能性)是计算有效本地时区的最可靠的方法。只要任意两个时区中至少有一个本地时间的UTC偏移量之间存在差异,这样的系统就可以正确地在它们之间进行选择。不幸的是,它返回的是一个由

Python 在我看来,这个算法和Anurag Uniyal提出的解决方案(只保留两种方法返回的可能性)是计算有效本地时区的最可靠的方法。只要任意两个时区中至少有一个本地时间的UTC偏移量之间存在差异,这样的系统就可以正确地在它们之间进行选择。不幸的是,它返回的是一个由,python,linux,datetime,timezone,localtime,Python,Linux,Datetime,Timezone,Localtime,在我看来,这个算法和Anurag Uniyal提出的解决方案(只保留两种方法返回的可能性)是计算有效本地时区的最可靠的方法。只要任意两个时区中至少有一个本地时间的UTC偏移量之间存在差异,这样的系统就可以正确地在它们之间进行选择。不幸的是,它返回的是一个由3个字母组成的时区代码元组,而不是完整的时区名称。即使为此建立查找表,也会产生歧义。“EST”可以是美国/纽约或澳大利亚/悉尼。“BST”可以是欧洲/伦敦或亚洲/达卡。他是对的。系统对其时区的唯一了解是GMT偏移量和DST设置。在linux上,



在我看来,这个算法和Anurag Uniyal提出的解决方案(只保留两种方法返回的可能性)是计算有效本地时区的最可靠的方法。只要任意两个时区中至少有一个本地时间的UTC偏移量之间存在差异,这样的系统就可以正确地在它们之间进行选择。

不幸的是,它返回的是一个由3个字母组成的时区代码元组,而不是完整的时区名称。即使为此建立查找表,也会产生歧义。“EST”可以是
美国/纽约
澳大利亚/悉尼
。“BST”可以是
欧洲/伦敦
亚洲/达卡
。他是对的。系统对其时区的唯一了解是GMT偏移量和DST设置。在linux上,这些由TZ环境变量(通常不设置)或/etc/localtime文件设置,该文件可以是指向/usr/share/zoneinfo中某个时区定义的链接,也可以是其中一个时区定义的副本。除非您确定正在运行脚本的系统是使用符号链接或环境变量配置的,否则无法一般地获取此值。然后,您可能可以从python中运行系统命令来获取它。@MattJoiner:如果您想获取环境变量的内容,可以使用os.getenv(“TZ”),或者解析返回的
ls-l/etc/localtime
,并从结果中提取链接路径。这里有一个完整的线程关于如何做到这一点:(调用ls,即,不是解析路径)因此,要清楚,您需要一种方法来确定Linux上当前用户区域设置的奥尔森时区名称(即
America/New_York
),正是。在这种情况下,我会主演这部电影,因为我也想知道:-)相似到足以让人产生一些想法。我想我的答案正确地列出了可能的匹配?您认为它在某些情况下会给出错误的结果吗?当/etc/localtime是一个符号链接时,它会起作用。大多数情况下情况并非如此,这一点出人意料地好。我想知道如果zoneinfo更新了,但是
/etc/localtime
没有更新,会发生什么。另外,我建议您立即切换到4空格缩进,而不是制表符(或8空格)。。。关于zoneinfo,我认为您的系统将没有tz,没有/etc/locatime,不是吗?不,我的意思是如果zoneinfo文件被更新,并且/etc/localtime不是一个符号链接。您可能有一个localtime不再匹配任何zoneinfo文件。在我的Ubuntu系统上,不幸的是,它返回zoneinfo/localtime。我同意,我认为这意味着用户可以轻松设置时区(例如,不知道UTC偏移)@Tilo:The bounty需要一个算法来生成这个时区名称列表。Ruby很简单(我在下面为Ruby添加了一个答案)。。。请检查pytz API,了解如何使用Python执行相同的操作。您能否重新确定国家代码,以便从更可靠的地方获得此值?在澳大利亚,
en_-US
并不少见,尽管存在
en_-AU
。最重要的是,我的名字是
'EST'
,所以你的算法给了我
美国/纽约
,但我在
澳大利亚/悉尼
。正在研究它。我可以假设web访问吗?该算法给出了迄今为止最好的结果,但它似乎没有@pcperini的答案那么清晰。@Matt Joiner,我认为它与它所比较的国家名称相比,在代码方面更清晰、更准确offsets@MattJoiner,此外,我认为从url获取的国家/地区代码不会改变。系统的TZ设置是否已更改?要了解DST是否有效:
如果time.daylight和time.localtime().tm_isdst>0
。注意:
time.daylight
along只告诉本地时区是否有DST,它不告诉任何关于当前状态的信息。ICU是否有问题,人们不喜欢答案?使用TZ环境变量仅适用于Linux(或Unix),不是Windows。另一件事是,它在我当前的Fedora(F20)上根本不起作用,没有定义这样的变量TZ。虽然这个链接可以回答这个问题,但最好在这里包含答案的基本部分,并提供链接供参考。如果链接页面发生更改,仅链接的答案可能无效。-两段解释是一个链接唯一的答案?我可以选择“这是一个评论,不回答问题。当你有足够的代表时,你就可以对这个问题发表评论。”但是,你有10000多个代表,因此感觉有点屈尊俯就。我认为它很好地回答了这个问题,否则我就不会浪费时间去做了。将关键过去日期和时间的UTC偏移量作为真实地区的线索,这是任何其他答案都无法提供的方法。你肯定不希望我在我的答案中重复精确的算法?如果“这个JavaScript项目”不再存在,你的答案几乎毫无用处。比较任意数量的UTC日期如何得出
澳大利亚/悉尼
的结果还不清楚。
#! /usr/bin/env python

import time

time.tzset
print time.tzname
>>>  import os
>>> '/'.join(os.readlink('/etc/localtime').split('/')[-2:])
'Australia/Sydney'
#!/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()
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
     "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"
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']
> 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
...
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
import time, pytz, os

cur_name=time.tzname
cur_TZ=os.environ.get("TZ")

def is_current(name):
   os.environ["TZ"]=name
   time.tzset()
   return time.tzname==cur_name

print "Possible choices:", filter(is_current, pytz.all_timezones)

# optional tz restore
if cur_TZ is None: del os.environ["TZ"]
else: os.environ["TZ"]=cur_TZ
time.tzset()
>>> from PyICU import ICUtzinfo
>>> from datetime import datetime
>>> datetime(2012, 1, 1, 12, 30, 18).replace(tzinfo=ICUtzinfo.getDefault()).isoformat()
'2012-01-01T12:30:18-05:00'
>>> datetime(2012, 6, 1, 12, 30, 18).replace(tzinfo=ICUtzinfo.getDefault()).isoformat()
'2012-06-01T12:30:18-04:00'
#!/usr/bin/env python

from hashlib import sha224
import os
from os import listdir
from os.path import join, isfile, isdir

infoDir = '/usr/share/zoneinfo/'

def get_current_olsonname():
    result = []
    tzfile_digest = sha224(open('/etc/localtime').read()).hexdigest()

    test_match = lambda filepath: sha224(open(filepath).read()).hexdigest() == tzfile_digest

    def walk_over(dirpath):
        for root, dirs, filenames in os.walk(dirpath):
            for fname in filenames:
                fpath = join(root, fname)
                if test_match(fpath):
                    result.append(tuple(root.split('/')[4:]+[fname]))

    for dname in listdir(infoDir):
        if dname in ('posix', 'right', 'SystemV', 'Etc'):
            continue
        dpath = join(infoDir, dname)
        if not isdir(dpath):
            continue
        walk_over(dpath)

    if not result:
        walk_over(join(infoDir))

    return result


if __name__ == '__main__':
    print get_current_olsonname()