Заставить Python реагировать на изменения часового пояса Windows - PullRequest
8 голосов
/ 05 декабря 2010

Когда Python работает под Windows, time.localtime не сообщает правильное время, если часовой пояс изменяется в течение времени жизни экземпляра Python. В Linux time.tzset всегда можно запустить, чтобы облегчить подобные проблемы, но в Windows нет аналога.

Есть ли способ исправить это, не делая ничего абсурдного, как, ну, я не знаю ...

#!/bin/env python
real_localtime = eval(subprocess.Popen(
    ["python","-c", "import time;repr(time.localtime())"],
    stdout=subprocess.PIPE).communicate()[0])

Ответы [ 3 ]

4 голосов
/ 06 декабря 2010

Более рациональное решение - использовать Kernel32 GetLocalTime с pywin32 или ctypes.Любые изменения часового пояса отражаются немедленно.

import ctypes
class SYSTEMTIME(ctypes.Structure):
    _fields_ = [
        ('wYear', ctypes.c_int16),
        ('wMonth', ctypes.c_int16),
        ('wDayOfWeek', ctypes.c_int16),
        ('wDay', ctypes.c_int16),
        ('wHour', ctypes.c_int16),
        ('wMinute', ctypes.c_int16),
        ('wSecond', ctypes.c_int16),
        ('wMilliseconds', ctypes.c_int16)]

SystemTime = SYSTEMTIME()
lpSystemTime = ctypes.pointer(SystemTime)
ctypes.windll.kernel32.GetLocalTime(lpSystemTime)
print SystemTime.wHour, SystemTime.wMinute 
3 голосов
/ 07 августа 2011

Суть в том, что с VC версии 6 tzset () не работает должным образом.Однако с VC версии 8 tzset () теперь работает (я думаю, что это может работать и в версии 7, но у меня нет этой версии для проверки).

Так что все, что должно произойти сейчас, это включить HAVE_WORKING_TZSET в исходном коде и перекомпилировать (и протестировать).

По моему опыту, все потребности функций для различных настроек TZ должны иметь работающий tzset (),Вы должны вызывать tzset () каждый раз, когда вы меняете C Lang TZ var -или- Windows TIME_ZONE_INFORMATION.Это было невозможно в VC версии 6, и поэтому HAVE_WORKING_TZSET не включен (но теперь он должен быть включен как минимум для VC версии 8 и выше).

Кстати.Для всего, что я делаю с датой и временем, у меня всегда есть SetUtcTime () и UnsetUtcTime (), которые устанавливают TZ в GMT и вызывают tzset () соответственно.У меня также есть функции для установки временного пояса.Это ЕДИНСТВЕННЫЙ способ сделать это правильно!По многолетнему опыту могу сказать, что все остальное - проблема.И calendar.timegm () не является правильным.Используйте tzset ().

Вот доказательство того, что оно теперь работает (поэтому обратитесь к автору ошибки, чтобы исправить код Windows):

(Я набрал это с другого компьютера, так что, надеюсь, никаких орфографических ошибок,но это точка, которую я делаю, а не код).


ПРИМЕЧАНИЕ: ВСЕ НИЖЕ - ПИФОН (я вызываю C Lang из интерфейса ctype Python) ПРИМЕЧАНИЕ: потому что я устанавливаю TZ через границу DLLздесь и нить локальная и вся эта хрень, ее нельзя использовать в качестве обходного пути.Необходимо повторно включить HAVE_WORKING_TZSET.

import time
from ctypes import *

dTime = time.time ()
nTime = int (dTime)
intTime = c_int (nTime)

print time.ctime (dTime)
print c_char_p (cdll.msvcrt.ctime (addressof (intTime))).value

-> ... 21:02:40 ... (python)
-> ... 21:02:40 ... (C lang)

cdll.msvcrt._putenv ('TZ=GMT')
cdll.msvcrt._tzset ()

(обычно вызывается time.tzset () и также вызывается inittimezone () для обновления переменных часового пояса python)

print time.ctime (dTime)
print c_char_p (cdll.msvcrt.ctime (addressof (intTime))).value

-> ... 21:02:40 ... (python)
-> ... 11:02:40 ... (C lang) <- базовый VC ver 8 работает сейчас! </p>

(так что если HAVE_WORKING_TZSETопределено для (версия 8 и выше) вы получите это:)

-> ... 11:02:40 ... (python)
-> ... 11:02:40... (C lang)


Просто проверьте исходный код, чтобы понять, что я имею в виду.

Я проверил это с последней версией Python '2.0': 2.7.2 только сейчас.

3 голосов
/ 06 декабря 2010

Нет, это нельзя исправить, не делая то, что вы сделали.Это немного абсурдно, но если вам нужен правильный часовой пояс в Windows, и он изменился во время выполнения программы, это должно быть сделано.

Это, вероятно, не ошибка (из документации очень ясно, чтофункция tzset() доступна только в Unix).Скорее всего, это слабость в Windows, которая не позволяет программистам Python реализовать tzset() под ней.Вы можете сделать запрос на улучшение функциональности, но так было начиная с Python 2.3 (7 лет), так что вряд ли он действительно будет реализован.

...