Python:如何获得datetime.today()是“时区感知”的值?
我想从datetime.today()
的值中减去一个date值来计算多久以前。 但它抱怨说:
TypeError: can't subtract offset-naive and offset-aware datetimes
值datetime.today()
似乎不是“时区意识”,而我的其他date值是。 如何获得datetime.today()
值的时区知道? 现在是在当地时间给我的时间,恰好是PST,即UTC-8小时。 最糟糕的情况,有没有办法我可以手动inputdatetime.today()
返回的datetime
对象的时区值并将其设置为UTC-8? 当然,理想的解决scheme是让它自动知道时区。
在标准库中,没有跨平台的方式来创build感知时区而不创build自己的时区类。
在Windows上,有win32timezone.utcnow()
,但这是pywin32的一部分。 我宁愿build议使用pytz库 ,它拥有大多数时区的最新数据库。
使用本地时区可能非常棘手(请阅读pytz文档!),所以您可能更希望在整个应用程序中使用UTC。 您可以像这样获取当前date/时间:
import pytz from datetime import datetime datetime.utcnow().replace(tzinfo=pytz.utc)
请注意, datetime.today()
和datetime.now()
返回的是本地时间,而不是UTC时间,所以向其中应用.replace(tzinfo=pytz.utc)
将是不正确的。
另一个好方法是:
datetime.now(pytz.utc)
这是有点短,也是一样的。
警告:
不要使用UTC时间以外的任何操作来进行date和时间的操作。 您可能会试图使用不同的时区来进行一些奇特的date时间操作,但是如果不注意,这可能会失败:
尝试:
d = datetime.datetime.now(pytz.timezone('America/Los_Angeles') >>> datetime.datetime(2017, 9, 14, 22, 18, 51, 892210, tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>) # add some days to the date that is in a localized timezone d = d + datetime.datetime.timedelta(days=90) >>> datetime.datetime(2017, 12, 13, 22, 18, 51, 892210, tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>)
这是错误的:应该是:
>>> datetime.datetime(2017, 12, 13, 21, 18, 51, 892210, tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 17:00:00 DST>)
由于夏时制的变化。
如果您在UTC时间执行此操作,然后将其转换为本地化时区:
d = datetime.datetime.now(pytz.UTC) >>> datetime.datetime(2017, 9, 15, 5, 34, 28, 716403, tzinfo=<UTC>) # Add offset in UTC time d = d + datetime.timedelta(days=90) >>> datetime.datetime(2017, 12, 14, 5, 34, 28, 716403, tzinfo=<UTC>) # Cast to local timezone d.astimezone(pytz.timezone('America/Los_Angeles')) >>> datetime.datetime(2017, 12, 13, 21, 34, 28, 716403, tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)
你得到正确的结果。
在特定的时区获取当前时间:
import datetime import pytz my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))
另一种构build表示当前时间的时区感知date时间对象的方法:
import datetime import pytz pytz.utc.localize( datetime.datetime.utcnow() )
这是一个可以在Python 2和Python 3上运行的stdlib解决scheme:
from datetime import datetime now = datetime.now(utc) # timezone-aware datetime.utcnow() today = datetime(now.year, now.month, now.day, tzinfo=utc) # midnight
其中today
是一个意识到的date时间实例,表示以UTC开头的一天(午夜),而utc
是一个tzinfo对象( 来自文档的示例 ):
from datetime import tzinfo, timedelta ZERO = timedelta(0) class UTC(tzinfo): def utcoffset(self, dt): return ZERO def tzname(self, dt): return "UTC" def dst(self, dt): return ZERO utc = UTC()
相关: 在给定UTC时间的几种方法获得午夜(开始一天)的性能比较。
注意:更复杂的是,对于具有不固定的utc偏移量的时区获得午夜 。
在Python 3中,标准库使得它更容易:
>>> import datetime >>> datetime.datetime.now(datetime.timezone.utc) datetime.datetime(2016, 8, 26, 14, 34, 34, 74823, tzinfo=datetime.timezone.utc)
如果您想要一个只使用标准库的解决scheme,并且可以在Python 2和Python 3中使用,请参阅JF Sebastien的答案 。
pytz是一个Python库,允许使用Python 2.3或更高版本进行准确的跨平台时区计算。
用stdlib,这是不可能的。
在SO上看到类似的问题。
如果你正在使用Django,你可以设置datenon-tz意识(只有utc)。
在settings.py中注释以下行:
USE_TZ = True
以下是使用stdlib生成它的一种方法:
import time from datetime import datetime FORMAT='%Y-%m-%dT%H:%M:%S%z' date=datetime.strptime(time.strftime(FORMAT, time.localtime()),FORMAT)
date将存储本地date和UTC的偏移量 ,而不是UTC时区的date,所以如果您需要确定在哪个时区生成date,则可以使用此解决scheme。 在这个例子中,在我的当地时区:
date datetime.datetime(2017, 8, 1, 12, 15, 44, tzinfo=datetime.timezone(datetime.timedelta(0, 7200))) date.tzname() 'UTC+02:00'
关键是将%z
指令添加到表示FORMAT,以指示生成的时间结构的UTC偏移量。 其他表示格式可以在date时间模块文档中查阅
如果您需要UTC时区的date,则可以用time.gmtime()replacetime.localtime()
date=datetime.strptime(time.strftime(FORMAT, time.gmtime()),FORMAT) date datetime.datetime(2017, 8, 1, 10, 23, 51, tzinfo=datetime.timezone.utc) date.tzname() 'UTC'
编辑
这只适用于python3 。 z指令在python 2 _strptime.py代码中不可用
为什么不使用dateutil这里描述: http ://joelinoff.com/blog/?p=802
from dateutil.tz import tzlocal # Get the current date/time with the timezone. now = datetime.datetime.now(tzlocal())
在utc
时区中获取一个可utc
时区的date就足以让date扣除工作。
但是如果你想在你当前的时区使用时区感知的date, tzlocal
就是要走的路:
from tzlocal import get_localzone # pip install tzlocal from datetime import datetime datetime.now(get_localzone())
PS dateutil
有一个类似的function( dateutil.tz.tzlocal
)。 但是,尽pipe共享名称,它有一个完全不同的代码基础,这正如JF塞巴斯蒂安所指出的 ,可以给出错误的结果。
如果你得到当前的时间和date在python然后导入date和时间,pytz包python之后,你会得到当前的date和时间,如..
from datetime import datetime import pytz import time str(datetime.strftime(datetime.now(pytz.utc),"%Y-%m-%d %H:%M:%S%t"))
- 将UTCdate时间转换为本地date时间
- 如何忽略用户的时区并强制Date()使用特定的时区
- 如何使MySQL的NOW()和CURDATE()函数使用UTC?
- 如何在Java中获取您的时区的当前date和时间?
- java.time.Clock.systemDefaultZone()。getZone()与java.util.TimeZone.getDefault()。toZoneId()之间的任何区别?
- 应用于时间戳时,具有相同属性的时区名称会产生不同的结果
- 如何使用JPA和Hibernate在UTC时区存储date/时间和时间戳
- 如何将时间转换为iPhone设备的时区?
- 如何在Java中使用TimeZone解决日光节约问题