【问题标题】:Why datetime.now() and datetime.today() show time in UTC and not local time on my PC?为什么 datetime.now() 和 datetime.today() 在我的 PC 上显示 UTC 时间而不是本地时间?
【发布时间】:2018-05-13 18:30:33
【问题描述】:

datetime.now()datetime.today() 在我的计算机上返回 UTC 时间,即使 the documentation 说他们应该返回本地时间。

这是我运行的脚本:

#!/usr/bin/python

import time
import datetime

if __name__ == "__main__":
   print(datetime.datetime.now())
   print(datetime.datetime.today())
   print(datetime.datetime.fromtimestamp(time.time()))

这是输出:

2017-11-29 22:47:35.339914
2017-11-29 22:47:35.340399
2017-11-29 22:47:35.340399

运行date之后的输出是:

Wed, Nov 29, 2017  3:47:43 PM

为什么我的安装返回时间是 UTC?
我该怎么做才能让这些函数返回本地时间?

PS我们在 MST,即 UTC-7。

PS 2 我知道有一些方法可以将 UTC 时间转换为本地时间,例如 Convert a python UTC datetime to a local datetime using only python standard library? 中解释的那些方法。但是,我试图了解根本问题的原因,而不是在自己的代码中寻找修补问题的方法。


回应@jwodder 的评论:

执行的输出

print(time.altzone)
print(time.timezone)
print(time.tzname)

是:

-3600
0
('Ame', 'ric')

【问题讨论】:

  • @rassar,感谢您的链接。它有有用的信息,但没有回答我的问题。
  • 您系统的时区可能设置为 UTC。 time.tzname and friends 有什么价值?
  • date 显示时区;如果你这样做date -R 那说明了什么?
  • 您的时区绝对是水管。我猜'Ame', 'ric'America 的开始。不知道那是怎么发生的。在我的机器上time.tzname 我得到('Pacific Standard Time', 'Pacific Daylight Time')。您没有指定您的操作系统等,但跟踪您的系统上的时区是如何设置的...

标签: python python-3.x datetime


【解决方案1】:

正如您在your answer 中所指出的,TZ 环境变量是这里的关键。在 unix 类型的系统上,这支持更“友好”的值,例如“US/Pacific”,或者实际上是“America/Denver”,但在 Windows 上,它不支持。尽管它在 Windows 上不可用,但 documentation for the time.tzset function 描述了设置 TZ 以获得所需内容所需的格式。这……不好看。但它有效:

C:\Users\zorb>set TZ=MST+07MDT,M3.2.0,M11.1.0
C:\Users\zorb>python.exe
>>> import time
>>> time.tzname
('MST', 'MDT')
>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2018, 2, 9, 16, 27, 7, 164062)

(这是太平洋时间 15:27。)这种格式的结构是:

  • 标准时间缩写 (MST)
  • 标准时间的 UTC 偏移量,以小时为单位 (+07)
  • 夏令时缩写
  • 夏令时开始时(见下文)
  • 白天结束时(见下文)

夏令时开始和结束的格式为:

  • M(用于“基于月份”)
  • 月份编号 - 在这种情况下为 3 月 3 日或 11 月 11 日。
  • 每月的第 1 周到第 5 周,表示以下日期的第 1 到第 5 天。
  • 星期几 - 0 代表星期日到 6 代表星期六

还有一些选项可以指定夏令时开始和结束的时间(但默认为 02:00:00,在这种情况下不需要)和夏令时的偏移量(但默认为 1 小时,所以也没有必要)。

(编辑)原来这实际上是一个 glibc 功能,而不是直接的 python 功能。更详细的信息在glibc docs

【讨论】:

  • 这听起来很有希望。我一定会根据您的建议进一步调查。
  • 很高兴听到这个消息!
【解决方案2】:

最初似乎是使用cygwin引起的问题。

Cygwin shows UTC time instead of local time 的问题有助于进一步将问题隔离到 cygwin 中环境变量 TZ 的值。

更新的脚本:

import time
import datetime

if __name__ == "__main__":
   print(datetime.datetime.now())
   print(datetime.datetime.today())
   print(datetime.datetime.fromtimestamp(time.time()))
   print(time.altzone)
   print(time.timezone)
   print(time.tzname)

在 Windows CMD shell 下运行时的输出,其中 TZ 未设置:

"D:\Program Files\Python35\python.exe" test.py
2017-11-30 09:39:47.236798
2017-11-30 09:39:47.236799
2017-11-30 09:39:47.236799
21600
25200
('Mountain Standard Time', 'Mountain Daylight Time')

在 cygwin bash shell 下运行时的输出,其中TZ 设置为"America/Denver"

 /cygdrive/D/Program\ Files/Python35/python.exe test.py
2017-11-30 16:39:45.419884
2017-11-30 16:39:45.419884
2017-11-30 16:39:45.419884
-3600
0
('Ame', 'ric')

设置为"America/Denver"。当我执行时

env TZ="" /cygdrive/D/Program\ Files/Python35/python.exe test.py

我得到了更明智的输出:

2017-11-30 09:56:08.643368
2017-11-30 09:56:08.643368
2017-11-30 09:56:08.643368
21600
25200
('Mountain Standard Time', 'Mountain Daylight Time')

当我在 windows CMD shell 中将环境变量 TZ 设置为 "America/Denver" 时,我得到的输出与在 cygwin shell 中运行时相同。

我不清楚 Python 如何使用环境变量 TZ 以及它的正确值是什么。

【讨论】:

  • 我永远不会使用 Cygwin 的另一个原因。
  • @NickT,cygwin 原来是一个红鲱鱼。真正的问题是,如果设置了环境变量TZ,即使只是在CMD控制台中,问题仍然存在。这是一个基本的 Python 问题。
  • 那么您是在 Cygwin shell 中使用非 Cygwin 版本的 Python 吗?那么是的,TZ 约定很可能是不兼容的。如果你想让 Python 理解 Unix 风格的 TZ 约定,最好使用 Cygwin 版本的 Python。
  • @Ove,理想情况下,是的。但是,有时这不是一个选择。
【解决方案3】:

我认为在 Windows 上使用 glibc 时间和时区库会出现一些奇怪的行为。我最近开始在 python 和 emacs 中注意到这种行为。

最好的办法可能是将 TZ 设置为最佳答案中描述的“丑陋”版本,因为这似乎可以解决 python 和 emacs 中的问题,并且在 cygwin 中也可以正常工作。

我尝试的另一个解决方法是确保设置了 TZ 环境变量 NOT。下面用python说明纽约时间10:18左右的问题。我在 Windows 上使用 cygwin 或 CMD 得到了类似的结果。 Emacs 使用 current-time-string 函数说明了同样的问题,这表明这是一个 glibc 问题,或者至少是 python 和 emacs 都在使用的某个库。有趣的是,cygwin 中的date 命令在 TZ 设置为“America/New York”时给出了正确的结果,但如果 TZ 未设置则不正确。

总结:Windows 上的某些东西(例如,python、emacs)似乎不接受 TZ 的“America/New_York”,而某些东西(例如,cygwin)确实接受它。在东部时间使用类似 EST+05EDT,M4.1.0,M10.5.0 的东西(或适当的丑陋等价物)是可行的。

$ echo $TZ
America/New_York

$ python -i
Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 10:22:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2018, 5, 14, 15, 38, 6, 174073)
>>> datetime.datetime.now()
datetime.datetime(2018, 5, 14, 15, 38, 57, 141708)
>>> quit()

$ export TZ=

$ python -i
Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 10:22:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2018, 5, 14, 10, 38, 41, 102117)

【讨论】:

  • 您是否尝试过使用已接受答案中建议的表格设置TZ
  • 是的。更新答案以反映这一点。谢谢。
猜你喜欢
  • 1970-01-01
  • 2015-06-20
  • 2019-03-05
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
  • 2021-03-09
  • 1970-01-01
相关资源
最近更新 更多