2010-12-05 4 views
7

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

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

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

Я могу подтвердить это, выглядит как ошибка для меня. – AndiDog 2010-12-05 20:51:02

+1

Зачем нужна оценка? – 2010-12-05 21:12:59

ответ

4

Более рациональное решение - использовать Kernel32's 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

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

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

3

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

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

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

BTW. Для всех дат/времени, которые у меня есть, у меня всегда есть SetUtcTime() и UnsetUtcTime(), который устанавливает TZ в GMT и вызывает tzset() соответственно. У меня также есть функции , чтобы установить темп в другой часовой пояс. Это ТОЛЬКО способ сделать это правильно! За многолетний опыт я могу сказать, что все остальное - проблема. А calendar.timegm() не соответствует . Используйте tzset().

Здесь не является доказательством того, что в настоящее время работает (так идти ошибка автора исправить код окна):

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


ПРИМЕЧАНИЕ: ВСЕ НИЖЕ IS ПИТОН (я называю C Ланг из интерфейса CTYPE питона) ПРИМЕЧАНИЯ: Потому что я устанавливаю 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 ... (питон)
-> ... 21:02:40 ...(C языки)

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

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

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 работает сейчас!

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

-> ... 11:02:40 ... (питон)
-> ... 11 : 02: 40 ... (C lang)


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

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