如何在Python中获得datetime.today()的值,即;时区感知“;?
我正在尝试从如何在Python中获得datetime.today()的值,即;时区感知“;?,python,datetime,date,timezone,Python,Datetime,Date,Timezone,我正在尝试从datetime.datetime.today()的值中减去一个日期值,以计算某物的存在时间。但它抱怨说: TypeError: can't subtract offset-naive and offset-aware datetimes 值datetime.datetime.today()似乎不是“时区感知”,而我的另一个日期值是。如何获取时区感知的datetime.datetime.today()值 现在,它给了我当地时间的时间,正好是太平洋标准时间,即UTC-8小时。最糟糕的
datetime.datetime.today()的值中减去一个日期值,以计算某物的存在时间。但它抱怨说:
TypeError: can't subtract offset-naive and offset-aware datetimes
值datetime.datetime.today()
似乎不是“时区感知”,而我的另一个日期值是。如何获取时区感知的datetime.datetime.today()
值
现在,它给了我当地时间的时间,正好是太平洋标准时间,即UTC-8小时。最糟糕的情况是,有没有办法手动将时区值输入到datetime.datetime.today()返回的datetime
对象中,并将其设置为UTC-8
当然,理想的解决方案是让它自动知道时区。是一个Python库,它允许使用Python 2.3或更高版本进行准确的跨平台时区计算
对于stdlib,这是不可能的
请参见标准库中的类似问题。在不创建自己的时区类的情况下,没有跨平台的方法来创建感知时区
在Windows上,有win32timezone.utcnow()
,但这是pywin32的一部分。我更愿意建议使用,它有一个不断更新的大多数时区数据库
使用本地时区可能非常棘手(请参阅下面的“进一步阅读”链接),因此您可能更希望在整个应用程序中使用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的原因:
- –许多实际用例的开发提示
- –关于时区工作复杂性的有趣、令人大开眼界的解释(视频)
构造表示当前时间的时区感知datetime对象的另一种方法:
import datetime
import pytz
pytz.utc.localize( datetime.datetime.utcnow() )
您可以通过运行以下命令从PyPI安装:
$ pipenv install pytz
获取特定时区中的当前时间:
import datetime
import pytz
my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))
date
datetime.datetime(2017, 8, 1, 12, 15, 44, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))
date.tzname()
'UTC+02:00'
请记住先安装。如果您使用的是Django,则可以设置不支持tz的日期(仅限)
注释settings.py中的以下行:
USE_TZ = True
下面是一个适用于Python 2和Python 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
是一个aware datetime实例,以UTC表示一天的开始(午夜),而UTC
是一个tzinfo对象():
相关:性能比较。
注意:使用dateutil更为复杂,如中所述:
在utc
时区中获取一个时区感知日期就足以实现日期减法
但是,如果您希望在当前时区中使用时区识别日期,tzlocal
是一个不错的选择:
from tzlocal import get_localzone # pip install tzlocal
from datetime import datetime
datetime.now(get_localzone())
PSdateutil
具有类似的功能(dateutil.tz.tzlocal
)。但是,尽管共享名称,但它有一个完全不同的代码库,正如J.F.Sebastian所说,这可能会给出错误的结果。这里有一种使用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时区的日期,因此,如果需要确定日期在哪个时区生成,可以使用此解决方案。在本例和我的本地时区中:
import datetime
import pytz
my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))
date
datetime.datetime(2017, 8, 1, 12, 15, 44, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))
date.tzname()
'UTC+02:00'
关键是将%z
指令添加到表示格式中,以指示生成的时间结构的UTC偏移量。可以在datetime模块中查阅其他表示格式
如果需要UTC时区的日期,可以将time.localtime()替换为time.gmtime()
编辑
这仅适用于python3。z指令在python 3.2+中的python 2上不可用:datetime.timezone.utc
:
通过标准库,可以更轻松地将UTC指定为时区:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2020, 11, 27, 14, 34, 34, 74823, tzinfo=datetime.timezone.utc)
您还可以使用以下方法获取包含本地时间偏移的日期时间:
(在Python 3.6+中,可以将最后一行缩短为:datetime.datetime.now().astimezone()
)
如果您想要一个只使用标准库且同时适用于Python 2和Python 3的解决方案,请参阅
在Python 3.9+中:zoneinfo
要使用IANA时区数据库:
在Python 3.9中,可以使用标准库指定特定时区,如下所示:
>>> from zoneinfo import ZoneInfo
>>> datetime.datetime.now(ZoneInfo("America/Los_Angeles"))
datetime.datetime(2020, 11, 27, 6, 34, 34, 74823, tzinfo=zoneinfo.ZoneInfo(key='America/Los_Angeles'))
zoneinfo
从操作系统或第一方PyPI包(如果可用)获取其时区数据库。如果在python中获取当前时间和日期,则在获取当前日期和时间后,导入日期和时间,pytz包(在python中),如下所示
from datetime import datetime
import pytz
import time
str(datetime.strftime(datetime.now(pytz.utc),"%Y-%m-%d %H:%M:%S%t"))
仅使用标准库的一行程序从Python 3.3开始就可以工作。您可以使用(as)获取本地时区感知的datetime
对象:
在我看来,另一个更好的选择是使用钟摆
而不是pytz
。考虑下面的简单代码:
>>> import pendulum
>>> dt = pendulum.now().to_iso8601_string()
>>> print (dt)
2018-03-27T13:59:49+03:00
>>>
要安装钟摆并查看其文档,请转到。它有大量的选项(如简单的ISO8601、RFC3339和许多其他格式支持)、更好的性能和更简单的代码 使用如下所示的时区作为时区感知日期时间。默认值为UTC:
from django.utils import timezone
today = timezone.now()
特别是对于非UTC时区:
唯一有自己方法的时区是timezone.utc
,但如果需要,您可以使用timedelta
&timezone
,强制使用。替换,以任意utc偏移量伪造时区
In [1]: from datetime import datetime, timezone, timedelta
In [2]: def force_timezone(dt, utc_offset=0):
...: return dt.replace(tzinfo=timezone(timedelta(hours=utc_offset)))
...:
In [3]: dt = datetime(2011,8,15,8,15,12,0)
In [4]: str(dt)
Out[4]: '2011-08-15 08:15:12'
In [5]: str(force_timezone(dt, -8))
Out[5]: '2011-08-15 08:15:12-08:00'
使用时区(timedelta(hours=n))
因为时区是这里真正的银弹,并且
>>> import pendulum
>>> dt = pendulum.now().to_iso8601_string()
>>> print (dt)
2018-03-27T13:59:49+03:00
>>>
from django.utils import timezone
today = timezone.now()
In [1]: from datetime import datetime, timezone, timedelta
In [2]: def force_timezone(dt, utc_offset=0):
...: return dt.replace(tzinfo=timezone(timedelta(hours=utc_offset)))
...:
In [3]: dt = datetime(2011,8,15,8,15,12,0)
In [4]: str(dt)
Out[4]: '2011-08-15 08:15:12'
In [5]: str(force_timezone(dt, -8))
Out[5]: '2011-08-15 08:15:12-08:00'
from pytz import timezone
datetime.now(timezone('Europe/Berlin'))
datetime.now(timezone('Europe/Berlin')).today()
import pytz
pytz.all_timezones
pytz.common_timezones # or
.replace(tzinfo=pytz.utc)
import pytz
import datetime from datetime
date = datetime.now().replace(tzinfo=pytz.utc)
>>> from pnp_datetime.pnp_datetime import Pnp_Datetime
>>>
>>> Pnp_Datetime.utcnow()
datetime.datetime(2020, 6, 5, 12, 26, 18, 958779, tzinfo=<UTC>)
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
today = datetime.utcnow()