FUNCTION_BLOCK "FB_LocalTime" TITLE = LocalTime { S7_Optimized_Access := 'FALSE' } AUTHOR : HReither FAMILY : DateTime NAME : LoclTime VERSION : 1.1 // // LocalTime V02.02P Freeware // (c) 26.09.2011..06.12.2011 Holger Reither // http://olbnet.selfhost.eu/reither/localtime.htm ) // // Wichtig !!!!! // ============= // Der Einsatzt dieses Bausteines erfolgt auf eigene // Gefahr! // Der Autor übernimmt keine Haftung für Schäden die // durch: // -falsche Handhabung des Bausteines auftreten, // -nach eigenmächtiger Veränderung des Bausteines, // -veraltete "Zeitzonenregeln" // entstehen. // Veraltete Zeitzonenregeln (1990 ... 9/2011) werden // nicht korrekt // behandelt (Bsp. 7 Moscow) !! // // Wer Änderungen vornimmt, wird gebeeten, diese // in der History (siehe unten) zu vermerken. // // Fehlermeldungen, Änderungswünsche, können Sie gerne // an oben genannte Mail-Adresse senden. // // Viel Erfolg mit LocalTime! // // =================================================== // // LocalTime errechnet aus der Systemzeit und der // vorgegebenen Zeitzone die Locale Zeit. // // Es wird vorausgesetzt, dass die Systemzeit UTC // entspricht! Das passt in der Regel, wenn Die Zeit // mit einem öffentlichen Zeitserver synchronisiert // wird. // // LocalTime übergibt die Lokale Zeit ohne // Beücksichtigung der Sommerzeit in der Variable // "LocalTimeWithoutDST". // LocalTime übergibt die Lokale Zeit mit // Beücksichtigung der Sommerzeit in der Variable // "LocalTimeWithDST". // // Für die meisten Zeitzonen wurde noch keine Regel // für die Sommerzeit-Umschaltung programmiert. Ist // eine solche Zeitzone angewählt // ("VAR_INPUT TimeZone"), so erhält die Variable // "VAR_OUTPUT LocalTimeWithDST" permanent den Wert // DT#1990-01-01-00:00:00.000 !! // // TimeZone Offset in h DST programmiert // 0 : London +0,0 // 1 : Paris +1,0 ja // 2 : Berlin +1,0 ja // 3 : Athens +2,0 // 4 : Cairo +2,0 // 5 : Jerusalem +2,0 // 6 : Jeddah +3,0 // 7 : Moscow +3,0 ja (korrekt erst ab Sommer 2011 !!) // 8 : Dubai +4,0 // 9 : Kabul +4,5 // 10 : Karachi +5,0 // 11 : Delhi +5,5 // 12 : Dhaka +6,0 // 13 : Yangon +6,5 // 14 : Bangkok +7,0 // 15 : Hong Kong +8,0 // 16 : Seoul +9,0 // 17 : Tokyo +9,0 // 18 : Adelaide +9,5 // 19 : Sydney +10,0 // 20 : Noumea +11,0 // 21 : Wellington +12,0 // 22 : -11,0 // 23 : Honululu -10,0 // 24 : Anchorage -9,0 // 25 : Los Angeles -8,0 // 26 : Denver -7,0 // 27 : Chicago -6,0 // 28 : New York -5,0 // 29 : Caracas -4,0 // 30 : Rio De Janeiro -3,0 // 31 : -2,0 // 32 : -1,0 // // // UTC : // Die koordinierte Weltzeit, international als UTC // (engl. „Coordinated Universal TIME“) abgekürzt, // ist die heute gültige Weltzeit. Eingeführt wurde // sie 1972. // Aus Zeitangaben in UTC erhält man die in // Deutschland und anderen mitteleuropäischen Staaten // geltende Mitteleuropäische Zeit (MEZ), // indem man eine Stunde addiert. // Um die im Sommer geltende Mitteleuropäische // Sommerzeit (MESZ) zu erhalten, muss man zwei // Stunden addieren. // (Quelle: Wikipedia) // // Erforderliche S7-Bausteine: // (FC1) AD_DT_TM addiert eine Zeitdauer // (Format TIME) auf einen // Zeitpunkt (Format DT) // (FC35) SB_DT_TM subtrahiert eine Zeitdauer // (Format TIME) von einem // Zeitpunkt (Format DT) // (SFC1) READ_CLK Auslesen der CPU-Zeit // // =================================================== // History: // // Änderung: ............................... // Geändert durch: ............................... // Datum: .......... // Kurzbeschreibung: ............................... // ............................... // ............................... // ............................... // ............................... // // // // // =================================================== // // // // VAR_INPUT "#UTCDayOfWeek:=DATE_TO_INT(DT_TO_DATE(#UTC));" : Int; END_VAR VAR_OUTPUT UTC : Date_And_Time; ArrayUTC { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} AT UTC : Array [ 0..7 ] of Byte; LocalTimeWithoutDST : Date_And_Time; LocalTimeWithDST : Date_And_Time; TimeZoneTxt : String[15]; OffsetTXT : String[5]; END_VAR VAR_TEMP UTCMonth : Int; UTCDay : Int; UTCHour : Int; UTCDayOfWeek : Int; Offset : Time; OffsetNeg : Bool; ErrSFC1 : Int; Schaltpunkt1 : Bool; Schaltpunkt2 : Bool; SommerzeitMitteleuropa : Bool; Tmp_Datum : Date; UTC_Date : Date; TageSeit_Mo_01_01_1990 : Int; WDay : Int; END_VAR BEGIN // LocalTime V02.02P Freeware // (c) 26.09.2011..06.12.2015 Holger Reither // http://olbnet.selfhost.eu/reither/localtime.htm ) // // Wichtig !!!!! // ============= // Der Einsatzt dieses Bausteines erfolgt auf eigene // Gefahr! // Der Autor übernimmt keine Haftung für Schäden die // durch: // -falsche Handhabung des Bausteines auftreten, // -nach eigenmächtiger Veränderung des Bausteines, // -veraltete "Zeitzonenregeln" // entstehen. // Veraltete Zeitzonenregeln (1990 ... 9/2011) werden // nicht korrekt // behandelt (Bsp. 7 Moscow) !! // // Wer Änderungen vornimmt, wird gebeeten, diese // in der History (siehe unten) zu vermerken. // // Fehlermeldungen, Änderungswünsche, können Sie gerne // an oben genannte Mail-Adresse senden. // // Viel Erfolg mit LocalTime! // // =================================================== // // LocalTime errechnet aus der Systemzeit und der // vorgegebenen Zeitzone die Locale Zeit. // // Es wird vorausgesetzt, dass die Systemzeit UTC // entspricht! Das passt in der Regel, wenn Die Zeit // mit einem öffentlichen Zeitserver synchronisiert // wird. // // LocalTime übergibt die Lokale Zeit ohne // Beücksichtigung der Sommerzeit in der Variable // "LocalTimeWithoutDST". // LocalTime übergibt die Lokale Zeit mit // Beücksichtigung der Sommerzeit in der Variable // "LocalTimeWithDST". // // Für die meisten Zeitzonen wurde noch keine Regel // für die Sommerzeit-Umschaltung programmiert. Ist // eine solche Zeitzone angewählt // ("VAR_INPUT TimeZone"), so erhält die Variable // "VAR_OUTPUT LocalTimeWithDST" permanent den Wert // DT#1990-01-01-00:00:00.000 !! // // TimeZone Offset in h DST programmiert // 0 : London +0,0 // 1 : Paris +1,0 ja // 2 : Berlin +1,0 ja // 3 : Athens +2,0 // 4 : Cairo +2,0 // 5 : Jerusalem +2,0 // 6 : Jeddah +3,0 // 7 : Moscow +3,0 wird nicht mehr angewendet // 8 : Dubai +4,0 // 9 : Kabul +4,5 // 10 : Karachi +5,0 // 11 : Delhi +5,5 // 12 : Dhaka +6,0 // 13 : Yangon +6,5 // 14 : Bangkok +7,0 // 15 : Hong Kong +8,0 // 16 : Seoul +9,0 // 17 : Tokyo +9,0 // 18 : Adelaide +9,5 // 19 : Sydney +10,0 // 20 : Noumea +11,0 // 21 : Wellington +12,0 // 22 : -11,0 // 23 : Honululu -10,0 // 24 : Anchorage -9,0 // 25 : Los Angeles -8,0 // 26 : Denver -7,0 // 27 : Chicago -6,0 // 28 : New York -5,0 // 29 : Caracas -4,0 // 30 : Rio De Janeiro -3,0 // 31 : -2,0 // 32 : -1,0 // // // UTC : // Die koordinierte Weltzeit, international als UTC // (engl. „Coordinated Universal TIME“) abgekürzt, // ist die heute gültige Weltzeit. Eingeführt wurde // sie 1972. // Aus Zeitangaben in UTC erhält man die in // Deutschland und anderen mitteleuropäischen Staaten // geltende Mitteleuropäische Zeit (MEZ), // indem man eine Stunde addiert. // Um die im Sommer geltende Mitteleuropäische // Sommerzeit (MESZ) zu erhalten, muss man zwei // Stunden addieren. // (Quelle: Wikipedia) // // Erforderliche S7-Bausteine: // (FC1) AD_DT_TM addiert eine Zeitdauer // (Format TIME) auf einen // Zeitpunkt (Format DT) // (FC35) SB_DT_TM subtrahiert eine Zeitdauer // (Format TIME) von einem // Zeitpunkt (Format DT) // (SFC1) READ_CLK Auslesen der CPU-Zeit // // =================================================== // History: // // Änderung: FC7 DT_DAY durch eigenen Programmcode ersetzt, // Fehlerbehebung: Zeitzone Moskau (3h Versatz / keine Sommerzeit) // Ab jetzt neue Bausteinversion: 02.01 // Geändert durch: Holger Reither // Datum: 09.11.2015 // // // // // // Änderung: ............................... // Geändert durch: ............................... // Datum: .......... // Kurzbeschreibung: ............................... // ............................... // ............................... // ............................... // ............................... // // // // // =================================================== // Begin --------------------------------------------------------------------------------------------------------------- CASE #"#UTCDayOfWeek:=DATE_TO_INT(DT_TO_DATE(#UTC));" OF 0 : #TimeZoneTxt:= 'London'; #OffsetTXT:= ' +0,0'; #Offset:= T#0h; #OffsetNeg:= false; 1 : #TimeZoneTxt:= 'Paris'; #OffsetTXT:= ' +1,0'; #Offset:= T#1h; #OffsetNeg:= false; 2 : #TimeZoneTxt:= 'Berlin'; #OffsetTXT:= ' +1,0'; #Offset:= T#1h; #OffsetNeg:= false; 3 : #TimeZoneTxt:= 'Athens'; #OffsetTXT:= ' +2,0'; #Offset:= T#2h; #OffsetNeg:= false; 4 : #TimeZoneTxt:= 'Cairo'; #OffsetTXT:= ' +2,0'; #Offset:= T#2h; #OffsetNeg:= false; 5 : #TimeZoneTxt:= 'Jerusalem'; #OffsetTXT:= ' +2,0'; #Offset:= T#2h; #OffsetNeg:= false; 6 : #TimeZoneTxt:= 'Jeddah'; #OffsetTXT:= ' +3,0'; #Offset:= T#3h; #OffsetNeg:= false; 7 : #TimeZoneTxt:= 'Moscow'; #OffsetTXT:= ' +3,0'; #Offset:= T#3h; // seit 2011 keine SZ-/ WZ- Umschaltung mehr #OffsetNeg:= false; 8 : #TimeZoneTxt:= 'Dubai'; #OffsetTXT:= ' +4,0'; #Offset:= T#4h; #OffsetNeg:= false; 9 : #TimeZoneTxt:= 'Kabul'; #OffsetTXT:= ' +4,5'; #Offset:= T#4h30m; #OffsetNeg:= false; 10: #TimeZoneTxt:= 'Karachi'; #OffsetTXT:= ' +5,0'; #Offset:= T#5h; #OffsetNeg:= false; 11: #TimeZoneTxt:= 'Delhi'; #OffsetTXT:= ' +5,5'; #Offset:= T#5h30m; #OffsetNeg:= false; 12: #TimeZoneTxt:= 'Dhaka'; #OffsetTXT:= ' +6,0'; #Offset:= T#6h; #OffsetNeg:= false; 13: #TimeZoneTxt:= 'Yangon'; #OffsetTXT:= ' +6,5'; #Offset:= T#6h30m; #OffsetNeg:= false; 14: #TimeZoneTxt:= 'Bangkoo'; #OffsetTXT:= ' +7,0'; #Offset:= T#7h; #OffsetNeg:= false; 15: #TimeZoneTxt:= 'Hong Kong'; #OffsetTXT:= ' +8,0'; #Offset:= T#8h; #OffsetNeg:= false; 16: #TimeZoneTxt:= 'Seoul'; #OffsetTXT:= ' +9,0'; #Offset:= T#9h; #OffsetNeg:= false; 17: #TimeZoneTxt:= 'Tokyo'; #OffsetTXT:= ' +9,0'; #Offset:= T#9h; #OffsetNeg:= false; 18: #TimeZoneTxt:= 'Adelaide'; #OffsetTXT:= ' +9,5'; #Offset:= T#9h30m; #OffsetNeg:= false; 19: #TimeZoneTxt:= 'Sydney'; #OffsetTXT:= '+10,0'; #Offset:= T#10h; #OffsetNeg:= false; 20: #TimeZoneTxt:= 'Noumea'; #OffsetTXT:= '+11,0'; #Offset:= T#11h; #OffsetNeg:= false; 21: #TimeZoneTxt:= 'Wellington'; #OffsetTXT:= '+12,0'; #Offset:= T#12h; #OffsetNeg:= false; 22: #TimeZoneTxt:= ''; #OffsetTXT:= '-11,0'; #Offset:= T#11h; #OffsetNeg:= true; 23: #TimeZoneTxt:= 'Honululu'; #OffsetTXT:= '-10,0'; #Offset:= T#10h; #OffsetNeg:= true; 24: #TimeZoneTxt:= 'Anchorage'; #OffsetTXT:= ' -9,0'; #Offset:= T#9h; #OffsetNeg:= true; 25: #TimeZoneTxt:= 'Los Angeles'; #OffsetTXT:= ' -8,0'; #Offset:= T#8h; #OffsetNeg:= true; 26: #TimeZoneTxt:= 'Denver'; #OffsetTXT:= ' -7,0'; #Offset:= T#7h; #OffsetNeg:= true; 27: #TimeZoneTxt:= 'Chicago'; #OffsetTXT:= ' -6,0'; #Offset:= T#6h; #OffsetNeg:= true; 28: #TimeZoneTxt:= 'New York'; #OffsetTXT:= ' -5,0'; #Offset:= T#5h; #OffsetNeg:= true; 29: #TimeZoneTxt:= 'Caracas'; #OffsetTXT:= ' -4,0'; #Offset:= T#4h; #OffsetNeg:= true; 30: #TimeZoneTxt:= 'Rio De Janeiro'; #OffsetTXT:= ' -3,0'; #Offset:= T#3h; #OffsetNeg:= true; 31: #TimeZoneTxt:= ''; #OffsetTXT:= ' -2,0'; #Offset:= T#2h; #OffsetNeg:= true; 32: #TimeZoneTxt:= ''; #OffsetTXT:= ' -1,0'; #Offset:= T#1h; #OffsetNeg:= true; ELSE: #TimeZoneTxt:= 'undefined'; #OffsetTXT:= ' +0,0'; #Offset:= T#0m; #OffsetNeg:= false; END_CASE; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Ermittle die Systemzeit // Es wird vorausgesetzt, dass die Systemzeit UTC entspricht ! #ErrSFC1 := RD_SYS_T(OUT => #UTC // OUT: DATE_AND_TIME ); // RetVal: INT // Zerlegen der Systemzeit #UTCMonth:=BCD16_TO_INT(BYTE_TO_WORD(#ArrayUTC[1])); #UTCDay:=BCD16_TO_INT(BYTE_TO_WORD(#ArrayUTC[2])); #UTCHour:=BCD16_TO_INT(BYTE_TO_WORD(#ArrayUTC[3])); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Ermittlung des UTC-Wochentages // Die Nummerierung entspricht dem früheren S7-Bausteine FC7 DT_DAY // 1 Sonntag / 2 Montag / 3 Dienstag / 4 Mittwoch / 5 Donnerstag / 6 Freitag / 7 Samstag #TageSeit_Mo_01_01_1990:=DATE_TO_INT(DT_TO_DATE(#UTC)); #WDay:=2+ (#TageSeit_Mo_01_01_1990 MOD 7); IF #WDay=8 THEN #WDay:=1; END_IF; #UTCDayOfWeek:=#WDay; // // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Errechne Lokalzeit ohne Beücksichtigung der Sommerzeit IF #OffsetNeg THEN #LocalTimeWithoutDST := T_SUB(IN1 := #UTC // IN: DATE_AND_TIME ,IN2:= #Offset // IN: TIME ); // DATE_AND_TIME ELSE #LocalTimeWithoutDST := T_ADD(IN1 := #UTC // IN: DATE_AND_TIME ,IN2:= #Offset // IN: TIME ); // DATE_AND_TIME END_IF; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Test auf Sommerzeit Mitteleuropa // Offizielle Regelung der Zeitumstellung // Folgende Regelung gilt: // // Die Umstellung von der Normal- auf die Sommerzeit findet am letzten Sonntag im März um 1 Uhr UTC, // also in der mitteleuropäischen Zeitzone von 2 Uhr MEZ auf 3 Uhr MESZ, statt. // // Die Umstellung von der Sommer- auf die Normalzeit findet am letzten Sonntag im Oktober um 1 Uhr UTC, // also in der mitteleuropäischen Zeitzone von 3 Uhr MESZ auf 2 Uhr MEZ, statt. // // Um die doppelt erscheinenden Stunden von 2 Uhr MESZ bis 3 Uhr MEZ am Ende der Sommerzeit // unterscheiden zu können, wird die Stunde vor der Zeitumstellung mit 2A Uhr, die Stunde nach der // Umstellung mit 2B Uhr bezeichnet. Die Bezeichnung mit A und B wurde in Deutschland erstmals in § 3 der // Bekanntmachung über die Sommerzeit 1917[6] eingeführt. Sie darf nicht verwechselt werden mit der // international üblichen Abkürzung der Zeitzonen, nach der 2 Uhr MESZ als 0200B und 2 Uhr MEZ als 0200A // bezeichnet werden. // (Quelle: Wikipedia) // Schaltpunkt1 (Winter->Sommer) // 25 26 27 28 29 30 31 März // 1So 2Mo 3Di 4Mi 5Do 6Fr 7Sa // 1So 2Mo 3Di 4Mi 5Do 6Fr // 1So 2Mo 3Di 4Mi 5Do // 1So 2Mo 3Di 4Mi // 1So 2Mo 3Di // 1So 2Mo // 1So #Schaltpunkt1 := (#UTCMonth>3) // März ist vergangen OR ((#UTCMonth=3) AND ( ((#UTCDayOfWeek=2)AND(#UTCDay>25)) // Resttage im März OR ((#UTCDayOfWeek=3)AND(#UTCDay>26)) OR ((#UTCDayOfWeek=4)AND(#UTCDay>27)) OR ((#UTCDayOfWeek=5)AND(#UTCDay>28)) OR ((#UTCDayOfWeek=6)AND(#UTCDay>29)) OR ((#UTCDayOfWeek=7)AND(#UTCDay>30)) OR ((#UTCDayOfWeek=1)AND(#UTCDay>24) // Schalttag letzter So im März AND (#UTCHour>1) // 1UhrUTC / 2UhrMEZ -> 3UhrMEZ ) ) ); // Schaltpunkt2 (Sommer->Winter) // 25 26 27 28 29 30 31 Oktober // 1So 2Mo 3Di 4Mi 5Do 6Fr 7Sa // 1So 2Mo 3Di 4Mi 5Do 6Fr // 1So 2Mo 3Di 4Mi 5Do // 1So 2Mo 3Di 4Mi // 1So 2Mo 3Di // 1So 2Mo // 1So #Schaltpunkt2 := (#UTCMonth>10) // Oktober ist vergangen OR ((#UTCMonth=10) AND ( ((#UTCDayOfWeek=2)AND(#UTCDay>25)) // Resttage im Oktober OR ((#UTCDayOfWeek=3)AND(#UTCDay>26)) OR ((#UTCDayOfWeek=4)AND(#UTCDay>27)) OR ((#UTCDayOfWeek=5)AND(#UTCDay>28)) OR ((#UTCDayOfWeek=6)AND(#UTCDay>29)) OR ((#UTCDayOfWeek=7)AND(#UTCDay>30)) OR ((#UTCDayOfWeek=1)AND(#UTCDay>24) // Schalttag letzter So im Oktober AND (#UTCHour>1) // 1UhrUTC / 3UhrMEZ -> 2UhrMEZ ) ) ); ; // Sommerzeit Mitteleuropa #SommerzeitMitteleuropa:= #Schaltpunkt1 AND NOT #Schaltpunkt2; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #SommerzeitMitteleuropa:= false; // weil Fehler .. am30.10.2015 wurde noch #SommerzeitMitteleuropa gesetzt !!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Errechne Lokalzeit mit Beücksichtigung der Sommerzeit #LocalTimeWithDST:=DT#1990-01-01-00:00:00.000; // ungültige Zeit, falls Regel nicht bekannt oder programmiert CASE #"#UTCDayOfWeek:=DATE_TO_INT(DT_TO_DATE(#UTC));" OF 1,2: // TimeZoneTxt:='Paris' 'Berlin'; // Schweiz, Österreich, IF #SommerzeitMitteleuropa THEN #LocalTimeWithDST := T_ADD(IN1 := #LocalTimeWithoutDST // IN: DATE_AND_TIME ,IN2:= T#1h // IN: TIME ); // DATE_AND_TIME ELSE #LocalTimeWithDST:= #LocalTimeWithoutDST; END_IF; 7: // TimeZoneTxt:='Moscow'; // Auch in Russland beginnt und endet die Sommerzeit an denselben Tagen wie in Mitteleuropa. // Dort stellt man die Uhr zwar auch um eine Stunde vor, im Ergebnis jedoch um zwei Stunden // gegenüber der jeweiligen Zonenzeit, weil die aus Sowjetzeiten fortgeltende so genannte Dekretzeit für // das ganze Jahr die Addition von einer Stunde zur jeweiligen Zonenzeit vorschreibt. Seit März 2011 wird // die Sommerzeit nicht mehr zurückgestellt.[28][29] // (Quelle: Wikipedia) // -> #LocalTimeWithDST:= #LocalTimeWithoutDST; END_CASE; END_FUNCTION_BLOCK |
Holger Reither