我试图从datetime.today()
的值中减去一个日期值来计算多久以前的事情。但它抱怨道:
TypeError: can't subtract offset-naive and offset-aware datetimes
值datetime.today()
似乎不是“时区感知”,而我的其他日期值是。如何获得时区感知的datetime.today()
值?现在它给了我当地时间的时间,恰好是PST,即UTC-8hrs。最坏的情况是,有没有办法我可以手动将时区值输入datetime
返回的datetime.today()
对象并将其设置为UTC-8?当然,理想的解决方案是让它自动知道时区。
答案 0 :(得分:305)
在标准库中,没有创建自己的时区类的创建感知时区的跨平台方式。
在Windows上,有win32timezone.utcnow()
,但这是pywin32的一部分。我宁愿建议使用pytz library,它有一个不断更新的大多数时区数据库。
使用本地时区可能非常棘手(请参阅下面的“进一步阅读”链接),因此您可能更愿意在整个应用程序中使用UTC,尤其是算术操作,例如计算两个时间点之间的差异。
您可以像这样获得当前日期/时间:
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:
答案 1 :(得分:90)
获取特定时区的当前时间:
import datetime
import pytz
my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))
答案 2 :(得分:42)
在Python 3中,标准库使得将UTC指定为时区变得更加容易:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2016, 8, 26, 14, 34, 34, 74823, tzinfo=datetime.timezone.utc)
如果您想要一个仅使用标准库并且同时适用于Python 2和Python 3的解决方案,请参阅J. F. Sebastien's answer。
答案 3 :(得分:17)
这是一个适用于Python 2和3的stdlib解决方案:
from datetime import datetime
now = datetime.now(utc) # timezone-aware datetime.utcnow()
today = datetime(now.year, now.month, now.day, tzinfo=utc) # midnight
其中today
是一个知晓的日期时间实例,表示以UTC开头的一天(午夜),而utc
是一个tzinfo对象(example from the docs):
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()
相关:several ways to get midnight (start of a day) for a given UTC time的效果比较 注意:它更复杂,get midnight for a time zone with a non-fixed utc offset。
答案 4 :(得分:13)
构造表示当前时间的时区感知日期时间对象的另一种方法:
import datetime
import pytz
pytz.utc.localize( datetime.datetime.utcnow() )
答案 5 :(得分:9)
如果您使用的是Django,则可以将日期设置为非tz(仅限utc)。
评论 settings.py中的以下行:
USE_TZ = True
答案 6 :(得分:6)
以下是使用stdlib生成它的一种方法:
import time
from datetime import datetime
FORMAT='%Y-%m-%dT%H:%M:%S%z'
date=datetime.strptime(time.strftime(FORMAT, time.localtime()),FORMAT)
日期将存储本地日期和偏离UTC ,而不是UTC时区的日期,因此如果您需要识别,可以使用此解决方案在生成日期的时区。在这个例子和我当地的时区:
date
datetime.datetime(2017, 8, 1, 12, 15, 44, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))
date.tzname()
'UTC+02:00'
关键是将%z
指令添加到表示FORMAT,以指示生成的时间结构的UTC偏移量。其他表示格式可以在日期时间模块docs
如果您需要UTC时区的日期,可以将 time.localtime()替换为 time.gmtime()
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 code
上不可用答案 7 :(得分:6)
答案 8 :(得分:4)
为什么不使用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())
答案 9 :(得分:4)
应该强调的是,从Python 3.6开始,您只需要标准的lib即可获取时区感知的datetime对象,该对象表示本地时间(操作系统的设置)。使用astimezone()
import datetime
datetime.datetime(2010, 12, 25, 10, 59).astimezone()
# e.g.
# datetime.datetime(2010, 12, 25, 10, 59, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'Mitteleuropäische Zeit'))
datetime.datetime(2010, 12, 25, 12, 59).astimezone().isoformat()
# e.g.
# '2010-12-25T12:59:00+01:00'
# I'm on CET/CEST
(请参阅@ johnchen902的评论)。请注意,astimezone(None) gives aware datetime, unaware of DST是一个小警告。
答案 10 :(得分:2)
您可以使用timezone
创建本地datetime
,方法是解析使用time.strftime
指令(在Python 3.3中引入)的%z
调用的输出,为{{ 3}}。您可以使用timezone
创建一个带有一行的知名datetime
实例:
import time
from datetime import datetime
aware_local_now = datetime.now(
tz=datetime.strptime(time.strftime("%z", time.localtime()), "%z").tzinfo)
print(aware_local_now)
2018-03-01 13:41:26.753644-08:00
答案 11 :(得分:2)
这是使用可读时区的解决方案,并且可以与today()一起使用:
from pytz import timezone
datetime.now(timezone('Europe/Berlin'))
datetime.now(timezone('Europe/Berlin')).today()
您可以列出所有时区,如下所示:
import pytz
pytz.all_timezones
pytz.common_timezones # or
答案 12 :(得分:1)
在utc
时区中获取时区感知日期足以使日期减法生效。
但是如果您想在当前时区中设置时区感知日期,tzlocal
就可以了:
from tzlocal import get_localzone # pip install tzlocal
from datetime import datetime
datetime.now(get_localzone())
PS dateutil
具有类似的功能(dateutil.tz.tzlocal
)。但是,尽管分享了这个名称,但它有一个完全不同的代码库,而J.F.Sebastian的noted可能会给出错误的结果。
答案 13 :(得分:1)
“ howchoo”中的泰勒写了一篇非常出色的文章,帮助我更好地了解了Datetime对象,请点击以下链接
基本上,我只是将以下内容添加到两个datetime对象的末尾
.replace(tzinfo=pytz.utc)
示例:
import pytz
import datetime from datetime
date = datetime.now().replace(tzinfo=pytz.utc)
答案 14 :(得分:0)
如果你在python中获得当前的时间和日期然后导入日期和时间,python包在python之后你会得到当前的日期和时间,如...
from datetime import datetime
import pytz
import time
str(datetime.strftime(datetime.now(pytz.utc),"%Y-%m-%d %H:%M:%S%t"))
答案 15 :(得分:0)
使用如下所示的时区作为时区感知日期时间,默认为UTC:
from django.utils import timezone
today = timezone.now()
答案 16 :(得分:0)
尝试pnp_datetime,所有使用和返回的时间都是时区,并且不会引起任何天真偏移和可感知偏移的问题。
>>> from pnp_datetime.pnp_datetime import Pnp_Datetime
>>>
>>> Pnp_Datetime.utcnow()
datetime.datetime(2020, 6, 5, 12, 26, 18, 958779, tzinfo=<UTC>)
答案 17 :(得分:0)
这对我有用,我首先尝试获取val counter = object: CountUpTimer(30, 1){
override fun onCount(count: Int) {
Log.i("Counter", "Counting: $count")
}
override fun onFinish() {
Log.i("Counter", "Counting done")
}
}
counter.start()
时间,然后根据您要设置的时区来增加或减少小时数。
UTC
答案 18 :(得分:-1)
在我看来,另一个替代方案是使用Pendulum
代替pytz
。请考虑以下简单代码:
>>> import pendulum
>>> dt = pendulum.now().to_iso8601_string()
>>> print (dt)
2018-03-27T13:59:49+03:00
>>>
要安装Pendulum并查看其文档,请转到here。它有很多选项(如简单的ISO8601,RFC3339和许多其他格式支持),更好的性能,并倾向于产生更简单的代码。