Es gibt von Siemens wohl tatsächlich keinen Baustein oder Anweisungen zum Umrechnen von Zeitstempeln in Systemzeit (UTC) zu Lokalzeit für S7-1200/S7-1500 ähnlich BT_LT für S7-300/S7-400. Ich habe mir eine Function UTC_TO_LOC_T in SCL programmiert. Vielleicht kann die noch jemand gebrauchen. Die SCL-Quelle im Anhang. Zum Verwenden mit TIA die Datei-Endung ".txt" entfernen.
Code:
FUNCTION "UTC_TO_LOC_T" : DTL
TITLE = UTC_TO_LOC_T
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : PN_DP
FAMILY : TIMEFUNC
VERSION : 1.0
//Konvertiert UTC zu einer europäischen Lokalzeit
VAR_INPUT
UTC {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; // Datum_Uhrzeit in UTC
TZ : Int; // Offset Zeitzone in Stunden (UTC+TZ)
DS : Int; // Differenz Sommerzeit zu Winterzeit (0 oder 1 Stunden)
END_VAR
VAR_OUTPUT
DST : Bool; // 0=Winterzeit / 1=Sommerzeit
END_VAR
VAR_TEMP
tmpDT {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; // lokale Kopie des Input UTC
tmpDS : Int; // Differenz Sommerzeit zu Winterzeit (0 oder 1 Stunden)
DiffTime : Time; // Differenz Zeitzone + ggf. Sommerzeit
IsSummer : Bool;
ui5Year4 : UInt; // Zwischenergebnis 5*Year/4
uiMDH_BeginDst : UInt; // Monat&Tag&Stunde Beginn Sommerzeit (dd März 01:00)
uiMDH_EndDst : UInt; // Monat&Tag&Stunde Ende Sommerzeit (dd Okt 01:00)
uiMDH_UTC : UInt; // Monat&Tag&Stunde des Input UTC
END_VAR
VAR CONSTANT
MULTIPLIER_MONTH : UInt := 32; // 32 Days per Month
MULTIPLIER_DAY : UInt := 24; // 24 Hours per Day
HOUR_01_00 : UInt := 1; // 01:00 Uhr
END_VAR
BEGIN
REGION BLOCK INFO HEADER
//===============================================================================
// Title : UTC_TO_LOC_T
// Author: PN_DP
// Konvertiert Datum_Uhrzeit UTC zu einer europäischen Lokalzeit
// mit angegebener Zeitzone und Sommerzeit-Differenz.
//
// Die Sommerzeit beginnt am letzten Sonntag im März 01:00 UTC
// Die Sommerzeit endet am letzten Sonntag im Oktober 01:00 UTC
// Input DS = 0: die Lokalzeit hat nie Sommerzeit
//
// Function für S7-1200/S7-1500. Erstellt mit TIA V15.1
// Version 01.00 | 14.04.2022
//===============================================================================
END_REGION
// Eingangsparameter für Konsistenz vorsichtshalber zu lokal umkopieren
#tmpDT := #UTC;
#tmpDS := #DS;
#DiffTime := T#1H * #TZ; // zunächst nur Offset Zeitzone
// Ermitteln ob Sommerzeit ist und ggf. Offset
IF #tmpDS = 0 THEN // wenn Sommerzeit wie Winterzeit, dann nur Offset Zeitzone
#IsSummer := FALSE;
ELSE
#ui5Year4 := 5 * (#tmpDT.YEAR MOD 100) / 4;
// Beginn Sommerzeit: Sonntag (31 - (5*Jahr/4 + 5) MOD 7) März 01:00 Uhr
#uiMDH_BeginDst := ( 3 * #MULTIPLIER_MONTH + (31 - ((#ui5Year4 + 5) MOD 7)) )
* #MULTIPLIER_DAY + #HOUR_01_00; //Mar DD 01:00
// Ende Sommerzeit: Sonntag (31 - (5*Jahr/4 + 2) MOD 7) Oktober 01:00 Uhr
#uiMDH_EndDst := (10 * #MULTIPLIER_MONTH + (31 - ((#ui5Year4 + 2) MOD 7)) )
* #MULTIPLIER_DAY + #HOUR_01_00; //Oct DD 01:00
// MMDDHH --> (MM*32 + DD)*24 + HH // (1..12*32 + 1..31)*24 + 0..23 = max 9983
#uiMDH_UTC := (#tmpDT.MONTH * #MULTIPLIER_MONTH + #tmpDT.DAY)
* #MULTIPLIER_DAY + #tmpDT.HOUR;
#IsSummer := #uiMDH_UTC >= #uiMDH_BeginDst AND #uiMDH_UTC < #uiMDH_EndDst;
IF #IsSummer THEN
#DiffTime := #DiffTime + T#1H * #tmpDS; // Offset Sommerzeit dazu
END_IF;
END_IF;
// Ausgangswerte zuweisen
#DST := #IsSummer;
#UTC_TO_LOC_T := #tmpDT + #DiffTime; //Lokalzeit zurückgeben
// no error handling
ENO := TRUE;
END_FUNCTION
Beim Aufruf von UTC_TO_LOC_T an TZ den Zeitzonen-Offset in Anzahl Stunden und an DS die Differenz der Sommerzeit zur Winterzeit in Anzahl Stunden angeben. Falls es in einer Zeitzone keine Sommerzeit (mehr) gibt, dann DS = 0 angeben. Zum Umrechnen von UTC zu CET/CEST den Baustein z.B. so aufrufen:
Code:
+----------------+
| UTC_TO_LOC_T |
--|EN Ret_Val|--"MyDB".DTL_LOC
"MyDB".DTL_UTC--|UTC DST|--"MyDB".IsSommerzeit
1--|TZ |
1--|DS ENO|--
+----------------+
Btw: Beim Test/Simulieren/Vergleichen mit RD_LOC_T ist mir aufgefallen, daß bei meinem TIA V15.1 das RD_LOC_T in der Sommerzeit eine falsche Uhrzeit liefert, wenn in der CPU das Sommerzeitbit nicht korrekt gesetzt ist. Also RD_LOC_T ermittelt die Sommerzeit nicht selbst anhand des Datums, sondern schaut lediglich, ob das Bit in der CPU gesetzt ist... Bei manchen CPU-Firmware-Versionen muß man selber dafür sorgen daß das Bit zur richtigen Zeit gesetzt/gelöscht wird.
Harald