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