Почему datetime.now() и datetime.today() показывают время в UTC, а не локальное время на моем ПК?

datetime.now() и datetime.today() время возврата в UTC на моем компьютере, хотя в документации говорится, что они должны возвращать местное время.

Здесь script Я побежал:

#!/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 в локальное время, например, в Преобразование даты и времени UTC в Python в локальное время используя только стандартную библиотеку python?. Тем не менее, я пытаюсь понять причину фундаментальной проблемы и не искать способ исправления проблемы в моем собственном коде.


В ответ на комментарий от @jwodder:

Результат выполнения

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

является:

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

Ответ 1

Как вы заметили в ваш ответ, здесь используется ключевая переменная TZ. В системах Unix-типа это поддерживает более "дружественные" значения, такие как "US/Pacific" или, действительно, "Америка/Денвер", но в Windows это не так. Несмотря на то, что он недоступен в Windows, документация для функции time.tzset описывает формат, который вам нужен, чтобы установить 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/марта или 11 ноября, в этом случае.
  • Неделя месяца - от 1 до 5, означающая первое-пятое появление дня, указанного ниже.
  • День недели - 0 для воскресенья с 6 по субботу.

Существуют также опции для указания времени, в которое начинается и заканчивается дневное время (но по умолчанию оно равно 02:00:00, поэтому в этом случае это лишнее) и смещение для дневного времени (но по умолчанию оно равно 1 часу, поэтому также не обязательно).

(edit) Оказывается, это на самом деле функция glibc, а не непосредственно python. Более подробная информация в glibc docs.

Ответ 2

Первоначально это была проблема, вызванная использованием cygwin.

Вопрос в Cygwin показывает время UTC вместо локального времени помог еще больше изолировать проблему до значения переменной окружения TZ в cygwin.

Обновленный script:

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 с, где 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 с, где 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')

Когда я устанавливаю переменную окружения TZ в "America/Denver" в оболочке CMD окон, я получаю тот же результат, что и при запуске в оболочке cygwin.

Мне непонятно, как Python использует переменную окружения TZ и какие для нее правильные значения.