如何在 Python 中获得“时区感知”的 datetime.today() 值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4530069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get a value of datetime.today() in Python that is "timezone aware"?
提问by mindthief
I am trying to subtract one date value from the value of datetime.today()to calculate how long ago something was. But it complains:
我试图从 的值中减去一个日期值datetime.today()来计算某物是多久以前的。但它抱怨:
TypeError: can't subtract offset-naive and offset-aware datetimes
The value datetime.today()doesn't seem to be "timezone aware", while my other date value is. How do I get a value of datetime.today()that is timezone aware?
该值datetime.today()似乎不是“时区感知”,而我的其他日期值是。我如何获得datetime.today()时区感知的值?
Right now, it's giving me the time in local time, which happens to be PST, i.e. UTC - 8 hours. Worst case, is there a way I can manually enter a timezone value into the datetimeobject returned by datetime.today()and set it to UTC-8?
现在,它给了我当地时间的时间,恰好是 PST,即 UTC - 8 小时。最坏的情况是,有没有一种方法可以手动将时区值输入到datetime返回的对象中datetime.today()并将其设置为 UTC-8?
Of course, the ideal solution would be for it to automatically know the timezone.
当然,理想的解决方案是让它自动知道时区。
采纳答案by AndiDog
In the standard library, there is no cross-platform way to create aware timezones without creating your own timezone class.
在标准库中,没有跨平台的方式来创建感知时区而不创建自己的时区类。
On Windows, there's win32timezone.utcnow(), but that's part of pywin32. I would rather suggest to use the pytz library, which has a constantly updated database of most timezones.
在 Windows 上,有win32timezone.utcnow(),但这是 pywin32 的一部分。我宁愿建议使用pytz 库,它具有大多数时区的不断更新的数据库。
Working with local timezones can be very tricky (see "Further reading" links below), so you may rather want to use UTC throughout your application, especially for arithmetic operations like calculating the difference between two time points.
使用本地时区可能非常棘手(请参阅下面的“进一步阅读”链接),因此您可能更愿意在整个应用程序中使用 UTC,尤其是对于计算两个时间点之间的差异等算术运算。
You can get the current date/time like so:
您可以像这样获取当前日期/时间:
import pytz
from datetime import datetime
datetime.utcnow().replace(tzinfo=pytz.utc)
Mind that datetime.today()and datetime.now()return the localtime, not the UTC time, so applying .replace(tzinfo=pytz.utc)to them would not be correct.
请注意datetime.today()并datetime.now()返回当地时间,而不是 UTC 时间,因此应用于.replace(tzinfo=pytz.utc)它们是不正确的。
Another nice way to do it is:
另一个不错的方法是:
datetime.now(pytz.utc)
which is a bit shorter and does the same.
这有点短,但也做同样的事情。
Further reading/watching why to prefer UTC in many cases:
进一步阅读/观看为什么在许多情况下更喜欢 UTC:
- pytz documentation
- What Every Developer Should Know About Time– development hints for many real-life use cases
- The Problem with Time & Timezones - Computerphile– funny, eye-opening explanation about the complexity of working with timezones (video)
- pytz 文档
- 每个开发人员都应该知道的关于时间的事情——许多现实生活用例的开发提示
- 时间和时区问题 - Computerphile- 关于使用时区的复杂性的有趣、令人大开眼界的解释(视频)
回答by user225312
回答by Dariusz Walczak
Another method to construct time zone aware datetime object representing current time:
构造表示当前时间的时区感知日期时间对象的另一种方法:
import datetime
import pytz
pytz.utc.localize( datetime.datetime.utcnow() )
回答by philfreo
Get the current time, in a specific timezone:
获取特定时区中的当前时间:
import datetime
import pytz
my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))
回答by laffuste
回答by jfs
Here's a stdlib solution that works on both Python 2 and 3:
这是一个适用于 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
where todayis an aware datetime instance representing the beginning of the day (midnight) in UTC and utcis a tzinfo object (example from the documentation):
哪里today是一个感知日期时间实例,表示 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()
Related: performance comparison of several ways to get midnight (start of a day) for a given UTC time. Note: it is more complex, to get midnight for a time zone with a non-fixed UTC offset.
相关:在给定 UTC 时间获得午夜(一天的开始)的几种方法的性能比较。注意:对于具有非固定 UTC offset 的时区获取午夜更为复杂。
回答by G. Führ
Use dateutil as described in Python datetime.datetime.now() that is timezone aware:
使用时区感知 Python datetime.datetime.now() 中所述的 dateutil :
from dateutil.tz import tzlocal
# Get the current date/time with the timezone.
now = datetime.datetime.now(tzlocal())
回答by Antony Hatchkins
Getting a timezone-aware date in utctimezone is enough for date subtraction to work.
在时区中获取时区感知日期utc足以使日期减法工作。
But if you want a timezone-aware date in your current time zone, tzlocalis the way to go:
但是,如果您想要当前时区中的时区感知日期,tzlocal那么方法是:
from tzlocal import get_localzone # pip install tzlocal
from datetime import datetime
datetime.now(get_localzone())
PS dateutilhas a similar function (dateutil.tz.tzlocal). But inspite of sharing the name it has a completely different code base, which as notedby J.F. Sebastian can give wrong results.
PSdateutil也有类似的功能(dateutil.tz.tzlocal)。但是,尽管共享名称,但它具有完全不同的代码库,正如JF Sebastian所指出的那样,这可能会产生错误的结果。
回答by jcazor
Here is one way to generate it with the stdlib:
这是使用 stdlib 生成它的一种方法:
import time
from datetime import datetime
FORMAT='%Y-%m-%dT%H:%M:%S%z'
date=datetime.strptime(time.strftime(FORMAT, time.localtime()),FORMAT)
datewill store the local date and the offset from UTC, not the date at UTC timezone, so you can use this solution if you need to identify which timezone the date is generated at. In this example and in my local timezone:
date将存储本地日期和与UTC的偏移量,而不是 UTC 时区的日期,因此如果您需要确定日期是在哪个时区生成的,则可以使用此解决方案。在这个例子和我的本地时区:
date
datetime.datetime(2017, 8, 1, 12, 15, 44, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))
date.tzname()
'UTC+02:00'
The key is adding the %zdirective to the representation FORMAT, to indicate the UTC offset of the generated time struct. Other representation formats can be consulted in the datetime module docs
关键是将%z指令添加到表示形式 FORMAT 中,以指示生成的时间结构的 UTC 偏移量。其他表示格式可以在 datetime 模块文档中查阅
If you need the date at the UTC timezone, you can replace time.localtime()with time.gmtime()
如果您需要 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'
Edit
编辑
This works only on python3. The z directive is not available on python 2 _strptime.py code
这仅适用于 python3。z 指令在 python 2 _strptime.py 代码上不可用
回答by Flimm
In Python 3, the standard library makes it much easier to specify UTC as the timezone:
在 Python 3 中,标准库可以更轻松地将 UTC 指定为时区:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2016, 8, 26, 14, 34, 34, 74823, tzinfo=datetime.timezone.utc)
If you want a solution that uses only the standard library and that works in both Python 2 and Python 3, see jfs' answer.
如果您想要一个仅使用标准库并且适用于 Python 2 和 Python 3 的解决方案,请参阅jfs 的回答。
If you need the local timezone, not UTC, see Mihai Capot?'s answer
如果您需要本地时区,而不是 UTC,请参阅Mihai Capot? 的答案

