12

PythonがWindowsで実行されている場合、Pythonインスタンスの存続期間中にタイムゾーンが変更された場合、time.localtimeは正しい時刻を報告しません。Linuxでは、このような問題を軽減するためにtime.tzsetをいつでも実行できますが、Windowsには同等のものがないようです。

ああ、わからないようなばかげたことをせずにこれを修正する方法はありますか...

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

3 に答える 3

8

より合理的な解決策は、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 
于 2010-12-05T23:44:02.530 に答える
4

いいえ、これはあなたがしたことをしなければ修正することはできません。少しばかげていますが、Windowsで正しいタイムゾーンが必要で、プログラムの実行中に変更された場合は、それを実行する必要があります。

これはおそらくバグではありません(ドキュメントは、tzset()関数がUnixでのみ利用可能であることを非常に明確にしています)。tzset()PythonプログラマーがWindowsの下で実装することを妨げるのは、Windowsの弱点である可能性が高いです。機能拡張をリクエストすることはできますが、Python 2.3(7年)からこのようになっているため、実際に実装される可能性はほとんどありません。

于 2010-12-05T21:21:07.730 に答える
4

つまり、VC ver 6では、tzset()が正しく機能しません。ただし、VC ver 8ではtzset()が機能するようになりました(ver 7でも機能する可能性がありますが、確認するバージョンがありません)。

したがって、今必要なのは、ソースコードでHAVE_WORKING_TZSETを有効にして、再コンパイル(およびテスト)することだけです。

私の経験では、TZのさまざまな設定に対する関数のすべてのニーズには、動作するtzset()が必要です。C Lang TZvarまたはWindowsTIME_ZONE_INFORMATIONを変更するときはいつでも、tzset()を呼び出す必要があります。これはVCver6では不可能でした。そのため、HAVE_WORKING_TZSETは有効になっていません(ただし、少なくともVC ver 8以降では有効になっているはずです)。

ところで。私が行うすべての日付/時刻については、常にSetUtcTime()とUnsetUtcTime()があり、TZをGMTに設定し、それに応じてtzset()を呼び出します。また、別のタイムゾーンに一時的に設定する機能もあります。これが適切に行う唯一の方法です!長年の経験で、私は他に何でも問題があると言うことができます。また、calendar.timegm()は正しくありません。tzset()を使用します。

これが現在機能している証拠です(したがって、バグの作成者にWindowsコードを修正してください):

(私はこれを別のコンピューターから入力したので、スペルミスがないことを願っていますが、コードではなく、私が作成したポイントです)。


注:以下はすべてPYTHONです(PythonのctypeインターフェイスからC Langを呼び出しています)注:ここではDLL境界を介してTZを設定し、ローカルスレッドとそのすべてのがらくたをスレッド化するため、回避策として使用できません。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が動作しています!

(したがって、HAVE_WORKING_TZSETが(バージョン8以降)に対して定義されている場合、これを取得します:)

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


ソースコードをチェックして、私が何を意味するかを確認してください。

私はこれを最新のpython'2.0'シリーズでチェックしました:2.7.2。

于 2011-08-07T11:48:08.340 に答える