GetDSDT() [UDF]

Veröffentliche deine funktionierenden Skripte und Funktionen

Moderator: jNizM

BoBo
Posts: 2515
Joined: 13 May 2014, 17:15

GetDSDT() [UDF]

28 Jul 2017, 03:47

Zu folgender anfrage: https://autohotkey.com/boards/viewtopic.php?f=5&t=28355
... hat 'just me' einen satz funktionen bereitgestellt, welcher eine lokale systemabfrage zur 'sommer/winterzeit' ermöglicht! :thumbup:

Dazu wird aus der registry die lokale zeitzone ermittelt - und darauf basierend, ob ein zeitraum für 'sommer/winterzeit' (DSDT/STDT) definiert ist.
Nun ist es einfach festzustellen, ob die aktuelle systemzeit innerhalb dieses zeitraums liegt. Dazu benutzen wir eine funktion von 'VxE'.

Code: Select all

; https://autohotkey.com/boards/viewtopic.php?p=161785#p161785 by 'just me' TZI2TIMEZONEINFORMATION() DateTimeFromSYSTEMTIME() GetWDayInMonth() ; https://autohotkey.com/board/topic/70962-need-program-to-determine-if-date-is-in-a-certain-range by '[VxE] nli' DateBetween() #NoEnv #SingleInstance, Force #Include DateBetween().ahk MsgBox % GetDSDT("start") ; retourniert den zeitstempel zum beginn der lokalen sommerzeit MsgBox % GetDSDT("e") ; retourniert den zeitstempel zum ende der lokalen sommerzeit MsgBox % GetDSDT("end") ; retourniert den zeitstempel zum ende der lokalen sommerzeit MsgBox % GetDSDT("period") ; retourniert den zeitstempel zur dauer/periode der lokalen sommerzeit MsgBox % GetDSDT() ; retourniert ob die lokale systemzeit innerhalb der lokalen sommerzeit liegt MsgBox % GetDSDT(20171029030000) ; retourniert das der 29.10.2017 03:00:00 (noch) innerhalb der lokalen sommerzeit liegt MsgBox % GetDSDT(20171029030001) ; retourniert das der 29.10.2017 03:00:01 (schon) außerhalb der lokalen sommerzeit liegt MsgBox % GetDSDT(20170330) ; retourniert das der 30.03.2017 bereits innerhalb der lokalen sommerzeit liegt GetDSDT(req="") { RegRead, TZ , HKLM,% "SYSTEM\CurrentControlSet\Control\TimeZoneInformation" , TimeZoneKeyName ; Ermitteln der lokalen zeitzone/timezone aus der registry RegRead, REGTZI , HKLM,% "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\" TZ , TZI ; Ermitteln der dazugehörigen 'time zone information' (binärer wert) TZI2TIMEZONEINFORMATION(REGTZI, TIMEZONEINFORMATION) DSDT := DateTimeFromSYSTEMTIME(&TIMEZONEINFORMATION + 152) ; Ausgabe lokale sommerzeit (beginn) aus der TZI im format YYYYMMDD24HHMMSS STDT := DateTimeFromSYSTEMTIME(&TIMEZONEINFORMATION + 68) ; Ausgabe lokale sommerzeit (ende) aus der TZI im format YYYYMMDD24HHMMSS If req Is Date Return % IsDateBetween(req,DSDT,STDT) = 0 ? "STDT" : "DSDT" res := (req = "start" || req = "s") ? DSDT : (req = "end" || req = "e") ? STDT : (req = "period"|| req = "p") ? DSDT "-" STDT : (req = "") ? IsDateBetween(A_Now,DSDT,STDT) = 0 ? "STDT" : "DSDT" ; Ermitteln ob das aktuelle systemdatum innerhalb des definierten zeitraum liegt (lokale sommerzeit) : "ERROR" Return % res } TZI2TIMEZONEINFORMATION(TZI, ByRef TIMEZONEINFORMATION) { ; Konvertiert 'time zone information'-werte in ein TIMEZONEINFORMATION struct Bias := 0 ; Bias StdD := 68 ; StandardDate StdB := 84 ; StandardBias DltD := 152 ; DaylightDate DltB := 168 ; DaylightBias VarSetCapacity(TIMEZONEINFORMATION, 172, 0) IR := -1 Addr := &TIMEZONEINFORMATION + Bias ; Bias Loop, 4 Addr := NumPut("0x" . SubStr(TZI, IR += 2, 2), Addr + 0, "UChar") Addr := &TIMEZONEINFORMATION + StdB ; StandardBias Loop, 4 Addr := NumPut("0x" . SubStr(TZI, IR += 2, 2), Addr + 0, "UChar") Addr := &TIMEZONEINFORMATION + DltB ; DaylightBias Loop, 4 Addr := NumPut("0x" . SubStr(TZI, IR += 2, 2), Addr + 0, "UChar") Addr := &TIMEZONEINFORMATION + StdD ; StandardDate Loop, 16 Addr := NumPut("0x" . SubStr(TZI, IR += 2, 2), Addr + 0, "UChar") Addr := &TIMEZONEINFORMATION + DltD ; DaylightDate Loop, 16 Addr := NumPut("0x" . SubStr(TZI, IR += 2, 2), Addr + 0, "UChar") } DateTimeFromSYSTEMTIME(Pointer) { Year := NumGet(Pointer + 0, "Short") Month := NumGet(Pointer + 2, "Short") Day := NumGet(Pointer + 6, "Short") Hour := NumGet(Pointer + 8, "Short") Min := NumGet(Pointer + 10, "Short") Sec := NumGet(Pointer + 12, "Short") If (Year = 0) && (Month <> 0) { Year := A_YYYY Day := GetWDayInMonth(Year, Month, NumGet(Pointer + 0, "Short") + 1, Day) } ; MsgBox % (Month = 0 ? "" : Format("{:04}-{:02}-{:02} {:02}:{:02}:{:02}", Year, Month, Day, Hour, Min, Sec)) ; Return (Month = 0 ? "" : Format("{:04}-{:02}-{:02} {:02}:{:02}:{:02}", Year, Month, Day, Hour, Min, Sec)) ; YYYY-MM-DD HH:MM:SS Return (Month = 0 ? "" : Format("{:04}{:02}{:02}{:02}{:02}{:02}", Year, Month, Day, Hour, Min, Sec)) ; YYYYMMDDHHMMSS } GetWDayInMonth(Year, Month, WDay, Occurence) { YearMonth := Format("{:04}{:02}01", Year, Month) If YearMonth Is Not Date Return 0 If WDay Not Between 1 And 7 Return 0 If Occurence Not Between 1 And 5 ; 5 = last occurence Return 0 FormatTime, WD, %YearMonth%, WDay While (WD <> WDay) { YearMonth += 1, D FormatTime, WD, %YearMonth%, WDay } While (A_Index <= Occurence) && (SubStr(YearMonth, 5, 2) = Month) { Day := SubStr(YearMonth, 7, 2) YearMonth += 7, D } Return Day }
8-)
Last edited by BoBo on 28 Jul 2017, 05:50, edited 4 times in total.
BoBo
Posts: 2515
Joined: 13 May 2014, 17:15

Re: GetDSDT() [UDF]

28 Jul 2017, 04:19

Frage an 'just me' ...
Ich habe nicht explizit nach der für die MESZ/CEST resultierenden zeitdifferenz geschaut (UTC+02:00).
Wäre diese jedoch noch in deinem funktionsatz gebunkert, ließe sich damit doch ggf (nach formatierung) der nackte UTC output deiner GetNetworkTime()-UDF bespaßen?!
Return % DateBetween(GetNetworkTime()[color=red]+zeitdifferenz[/color],DSDT,STDT) = 0 ? "STDT" : "DSDT"
just me
Posts: 5563
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GetDSDT() [UDF]

28 Jul 2017, 05:41

Ich denke mal darüber nach.
just me
Posts: 5563
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GetDSDT() [UDF]

28 Jul 2017, 06:26

Sodele, die Funktion TZI2TIMEZONEINFORMATION()versorgt auch die Zeitdifferenzen (Bias) in der TIME_ZONE_INFORMATION Struktur. Diese Differenzen sind in Minuten abgelegt. Du kannst sie Dir von dort wie folgt holen:

Code: Select all

; Bias: Abweichung UTC <> lokale Zeit in Minuten Bias := NumGet(TIMEZONEINFORMATION, 0, "Int") ; StandardBias: zusätzliche Abweichung während der Standardzeit in Minuten - bisher immer 0 StdB := NumGet(TIMEZONEINFORMATION, 84, "Int") ; DaylightBias: zusätzliche Abweichung während der Sommerzeit in Minuten DltB := NumGet(TIMEZONEINFORMATION, 168, "Int")
Die Umrechnung UTC <> lokale Zeit ist zunächst einmal so definiert:

Code: Select all

UTC := LokaleZeit + Bias + StandardBias ; bzw. LokaleZeit := UTC - Bias - StandardBias
Während der Sommerzeit kommt noch ein +/- DaylightBias dazu.
BoBo
Posts: 2515
Joined: 13 May 2014, 17:15

Re: GetDSDT() [UDF]

28 Jul 2017, 06:32

Sodele, die Funktion TZI2TIMEZONEINFORMATION()versorgt auch die Zeitdifferenzen (Bias) in der TIME_ZONE_INFORMATION Struktur. Diese Differenzen sind in Minuten abgelegt. Du kannst sie Dir von dort wie folgt holen:

[...]

Während der Sommerzeit kommt noch ein +/- DaylightBias dazu.
Als hätte ich es geahnt :lol: :thumbup: Wo doch in der US politik aktuell sehr oft der begriff "biased" auftaucht :wtf:
Thx für die recherche zur erweiterten funktionalität! M(u..) a(p..) !! ;)

(Fast) letzte frage, welche aufgabe hat die funktion GetWDayInMonth(), heißt, in welchem kontext wird diese information benötigt ??
Merci fürs schlaumachen :)
just me
Posts: 5563
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GetDSDT() [UDF]

28 Jul 2017, 08:28

Das ist der 'trickreiche' Teil. Die Schaltzeiten für die Sommer- und Winterzeit können entweder auf einem festen Datum liegen (immer am 01.04.) oder variabel sein (letzter Sonntag im März).

Bei festen Daten enthält die Registry die Information Jahr, Monat, Tag, Stunde, Minute, Sekunde. Zur Bestimmung des Datums muss dann nur das Jahr gegen das gewünschte ausgetauscht werden.

Bei variablen Daten ist das Jahr 0 und Tag enthält das Vorkommen des gewünschten Wochentags (WDay, 1 - 5, 5 = letzter), der hier ebenfalls angegeben sein muss (DayOfWeek). Für die Berechnung müssen dann das gewünschte Jahr eingesetzt und der zugehörige Tag ermittelt werden. Das macht GetWDayInMonth().

Das Verfahren hat Microsoft in der Beschreibung zu TIME_ZONE_INFORMATION dokumentiert.

Return to “Skripte und Funktionen”

Who is online

Users browsing this forum: No registered users and 2 guests