ZeitKorrektur Eventlog Sommer-/Winterzeit

  • Hallo zusammen,
    ich lese im Eventlog die Zeiten für das Starten und Herunterfahren meines Rechners aus um meine Anwesenheit zu erfassen. Funktion _EventLog__Read
    Leider werden die Zeiten aus der Winterzeit um eine Stunde ausgelesen.

    Meine Überlegung: Mit den Funktionen:
    _Date_GetSummerTime02 (https://www.autoit.de/index.php?page=Thread&threadID=5745)
    ermitteln ob das Ereignis in der Winter oder Sommerzeit geschrieben wurde.

    _Date_Time_GetTimeZoneInformation ( )
    ermitteln ob ich mich z.Z. in der Sommer oder Winterzeit befinde.
    und bei unterschiedlichen Ergebnissen eine Korrektur durchführen.

    Subjektiv empfinde ich das als zu aufwändig (und damit auch zu fehleranfällig) für eine so kleine Korrektur. Hat jemand von euch eine bessere Lösung.

    Vielen Dank
    sklaes

  • Hatte das bei den Eventlogs mal mit der API-Funktion SystemTimeToTzSpecificLocalTime umgesetzt:

    Eventlog Hoch/Runterfahren
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <ListViewConstants.au3>
    #include <StructureConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    #Region GUI
    Opt("GUIOnEventMode", 1)
    GUICreate("Eventlog reader", 851, 317, 241, 278)
    GUISetOnEvent($GUI_EVENT_CLOSE, "beenden")
    $ListView1 = GUICtrlCreateListView("Datum|Uhrzeit|Event-ID", 8, 28, 408, 278)
    GUICtrlSendMsg(-1, 0x101E, 0, 150)
    GUICtrlSetFont(-1, 8, 400, 0, "Arial")
    $ListView2 = GUICtrlCreateListView("Datum|Uhrzeit|Event-ID", 432, 28, 408, 278)
    GUICtrlSendMsg(-1, 0x101E, 0, 150)
    GUICtrlSetFont(-1, 8, 400, 0, "Arial")
    GUICtrlCreateLabel("Hochgefahren:", 8, 8, 105, 20)
    GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif")
    GUICtrlCreateLabel("Heruntergefahren:", 440, 8, 114, 20)
    GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif")
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    Func beenden()
    Exit
    EndFunc ;==>beenden
    #EndRegion GUI

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $o_WMI = ObjGet("winmgmts:\\localhost\root\CIMV2")
    Global $s_Query = "Select EventCode, TimeWritten, RecordNumber from Win32_NTLogEvent WHERE Logfile='System' AND (EventCode=6009 OR EventCode=6006)"
    Global $o_Col = $o_WMI.ExecQuery($s_Query, "WQL", 48)

    [/autoit] [autoit][/autoit] [autoit]

    For $o_Item In $o_Col
    With $o_Item
    $a_DT = WMIDateTime2LocalDateTimeString(.TimeWritten)
    If @error Then ContinueLoop
    GUICtrlCreateListViewItem($a_DT[0] & "|" & $a_DT[1] & "|" & .RecordNumber, (.EventCode = 6009) ? $ListView1 : $ListView2)
    EndWith
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ; Message Loop des GUI
    Do
    Sleep(100)
    Until 0

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Wandelt einen WMI-UTC-DateTime-String in Datum- und Zeit-Strings lokaler Zeit in deutscher Notation
    Func WMIDateTime2LocalDateTimeString(Const $s_WMIDT, Const $bMS = False)
    ; By AspirinJunkie
    If Not StringRegExp($s_WMIDT, "^\d{14}\.\d{6}-\d{3}$") Then Return SetError(1, 0, Null)
    Local $tDT = DllStructCreate($tagSYSTEMTIME)
    $tDT.Month = Int(StringMid($s_WMIDT, 5, 2), 1)
    $tDT.Day = Int(StringMid($s_WMIDT, 7, 2), 1)
    $tDT.Year = Int(StringLeft($s_WMIDT, 4), 1)
    $tDT.Hour = Int(StringMid($s_WMIDT, 9, 2), 1)
    $tDT.Minute = Int(StringMid($s_WMIDT, 11, 2), 1)
    $tDT.Second = Int(StringMid($s_WMIDT, 13, 2), 1)
    $tDT.MSeconds = Int(StringMid($s_WMIDT, 16, 6), 1)

    [/autoit] [autoit][/autoit] [autoit]

    Local $tDTL = DllStructCreate($tagSYSTEMTIME)
    DllCall("kernel32.dll", "BOOL", "SystemTimeToTzSpecificLocalTime", "STRUCT*", Null, "STRUCT*", $tDT, "STRUCT*", $tDTL)
    If @error Then Return SetError(2, @error, Null)

    [/autoit] [autoit][/autoit] [autoit]

    Local $a_Ret[] = [StringFormat("%02d.%02d.%04d", $tDTL.Day, $tDTL.Month, $tDTL.Year), StringFormat("%02d:%02d:%02d", $tDTL.Hour, $tDTL.Minute, $tDTL.Second) & ($bMS ? StringFormat(".%06d", $tDTL.MSeconds) : "")]
    Return $a_Ret
    EndFunc ;==>WMIDateTime2LocalDateTimeString

    [/autoit]


    Die Quelle für das Ganze ging während des Servercrashs flöten - im Google-Cache ist es aber noch enthalten:Thread im Google-Cache

    Hier mal als Nachweis, dass die Funktion tatsächlich Sommer/Winterzeit korrekt beachtet:

    Test auf Sommer/Winterzeit der Funktion WMIDateTime2LocalDateTimeString
    [autoit]

    #include <StructureConstants.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $s_TimeWinter = "20140101120000.000000-000"
    $a_Ret = WMIDateTime2LocalDateTimeString($s_TimeWinter)
    _ArrayDisplay($a_Ret, "Winterzeit")

    [/autoit] [autoit][/autoit] [autoit]

    $s_TimeWinter = "20140701120000.000000-000"
    $a_Ret = WMIDateTime2LocalDateTimeString($s_TimeWinter)
    _ArrayDisplay($a_Ret, "Sommerzeit")

    [/autoit] [autoit][/autoit] [autoit]

    ; Wandelt einen WMI-UTC-DateTime-String in Datum- und Zeit-Strings lokaler Zeit in deutscher Notation
    Func WMIDateTime2LocalDateTimeString(Const $s_WMIDT, Const $bMS = False)
    ; By AspirinJunkie
    If Not StringRegExp($s_WMIDT, "^\d{14}\.\d{6}-\d{3}$") Then Return SetError(1, 0, Null)
    Local $tDT = DllStructCreate($tagSYSTEMTIME)
    $tDT.Month = Int(StringMid($s_WMIDT, 5, 2), 1)
    $tDT.Day = Int(StringMid($s_WMIDT, 7, 2), 1)
    $tDT.Year = Int(StringLeft($s_WMIDT, 4), 1)
    $tDT.Hour = Int(StringMid($s_WMIDT, 9, 2), 1)
    $tDT.Minute = Int(StringMid($s_WMIDT, 11, 2), 1)
    $tDT.Second = Int(StringMid($s_WMIDT, 13, 2), 1)
    $tDT.MSeconds = Int(StringMid($s_WMIDT, 16, 6), 1)

    [/autoit] [autoit][/autoit] [autoit]

    Local $tDTL = DllStructCreate($tagSYSTEMTIME)
    DllCall("kernel32.dll", "BOOL", "SystemTimeToTzSpecificLocalTime", "STRUCT*", Null, "STRUCT*", $tDT, "STRUCT*", $tDTL)
    If @error Then Return SetError(2, @error, Null)

    [/autoit] [autoit][/autoit] [autoit]

    Local $a_Ret[] = [StringFormat("%02d.%02d.%04d", $tDTL.Day, $tDTL.Month, $tDTL.Year), StringFormat("%02d:%02d:%02d", $tDTL.Hour, $tDTL.Minute, $tDTL.Second) & ($bMS ? StringFormat(".%06d", $tDTL.MSeconds) : "")]
    Return $a_Ret
    EndFunc ;==>WMIDateTime2LocalDateTimeString

    [/autoit]

    Einmal editiert, zuletzt von AspirinJunkie (25. August 2014 um 17:29)