好的,我先说我的时区是CET/CEST。从CEST到CET(从DST(即GMT+2)到normal(即GMT+1)的确切时间总是10月的最后一个星期日凌晨3点。2010年是10月31日凌晨3点。
请注意以下几点:
>>> import datetime
>>> import pytz.reference
>>> local_tnz = pytz.reference.LocalTimezone()
>>> local_tnz.utcoffset(datetime.datetime(2010, 10, 31, 2, 12, 30))
datetime.timedelta(0, 3600)
如前所述,这是错误的。
>>> local_tnz.utcoffset(datetime.datetime(2010, 10, 30, 2, 12, 30))
datetime.timedelta(0, 7200)
>>> local_tnz.utcoffset(datetime.datetime(2010, 10, 31, 2, 12, 30))
datetime.timedelta(0, 7200)
现在它突然变得正确了:
我知道已经有几个关于这个的问题,但是给出的解决方案总是“使用本地化”,但是我这里的问题是LocalTimezone没有提供这个方法。
事实上,我有几个时间戳(以毫秒为单位),我需要本地时区的utcoffset(不仅是我的,而且是任何使用该程序的人的)。其中之一是1288483950000或2010年10月31日星期日02:12:30 GMT+0200(CEST)在我的时区。
当前,我执行以下操作以获取datetime对象:
datetime.datetime.fromtimestamp(int(int(millis)/1E3))
在几分钟内就能拿到utcoffset:
-int(local_tnz.utcoffset(date).total_seconds()/60)
不幸的是,这在很多情况下都是错误的:(。
有什么想法吗?
注意:我使用的是python3.2.4,在这种情况下这不重要。
编辑:
通过@JamesHolderness找到了解决方案:
def datetimeFromMillis(millis):
return pytz.utc.localize(datetime.datetime.utcfromtimestamp(int(int(millis)/1E3)))
def getTimezoneOffset(date):
return -int(date.astimezone(local_tz).utcoffset().total_seconds()/60)
使local_tz等于tzlocal。从tzlocal模块中获取_localzone()。
根据Wikipedia,夏令时和夏令时的转换发生在协调世界时01:00。
在UTC时间00:12,您仍处于中欧夏令时(即UTC+02:00),因此当地时间为02:12。
在UTC时间01:12,您又回到了标准中欧时间(即UTC+01:00),因此本地时间又是02:12。
当从夏季时间改回标准时间时,当地时间从02:59变回02:00,并且时间会重复。因此,当要求02:12(当地时间)的UTC偏移量时,答案可能是+01:00或+02:00—这取决于您所说的02:12的版本。
在进一步研究pytz库时,我认为您的问题可能是不应该使用pytz.reference实现,因为它可能无法很好地处理这些模糊性。引用源代码中的注释:
在pytz中处理不明确的时间
您应该做的是为适当的时区构造一个时区对象:
然后可以使用UTC offset方法计算该时区中日期/时间的UTC偏移量。
注意,上面的示例将抛出一个模糊的ustimeerror异常,因为它无法区分您指的是02:12:30的两个版本中的哪一个。幸运的是,pytz将允许您通过设置is dst参数来指定是要dst版本还是标准版本。例如:
请注意,在所有对utcoffset的调用上设置此参数并没有坏处,即使时间不会模棱两可。根据文档,它仅在DST转换不明确期间使用,以解决该不明确。
如何处理时间戳
至于处理时间戳,最好将它们存储为尽可能长的UTC值,否则可能会丢弃有价值的信息。因此,首先使用datetime.utcfromtimestamp方法转换为UTC日期时间。
然后使用pytz将时间本地化为UTC,以便将时区附加到datetime对象。
最后,您可以将该UTC日期时间转换为本地时区,并获得如下时区偏移量:
请注意,这组计算将生成1288483950和1288487550的正确偏移量,即使这两个时间戳在CET时区中都用02:12:30表示。
确定本地时区
如果需要使用计算机的本地时区而不是固定时区,则不能直接从pytz执行此操作。您也不能使用time.tzname中的时区名称来构造pytz.timezone对象,因为pytz不会始终识别这些名称。
解决方案是使用tzlocal module-其唯一目的是在pytz中提供这个缺少的功能。你这样使用它:
get_localzone()函数返回一个pytz.timezone对象,因此您应该能够在我在上面示例中使用过cet变量的所有地方使用该值。
给定时间戳(以毫秒为单位),您可以仅使用stdlib获取本地时区的utc偏移量:
如果我们忽略闰秒附近的时间,那么就没有模糊性或不存在的时间。
如果OS维护一个历史时区db,它支持DST和更改utc偏移量,例如,对于任何过去/现在的日期,它都应该在Ubuntu上工作,但是对于使用不同utc偏移量的过去日期,它可能会在Windows上中断。
使用^{} 模块在*nix和Win32系统上也一样:
见How to convert a python utc datetime to a local datetime using only python standard library?
要以分钟为单位获取utc偏移量(Python 3.2+):
不要使用
pytz.reference.LocalTimezone()
,it is only for tests。相关问题 更多 >
编程相关推荐