LTIME_TO_UTC

Begonnen von Terminator95, 02. August 2009, 18:49:08

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 2 Gäste betrachten dieses Thema.

Terminator95

Hallo, ich habe folgendes Problem.

Mit SysRTCGetTime hole ich mir die aktuelle Lokalzeit, diese möchte ich dann mit LTIME_TO_UTC umwandeln in UTC. DST ist natürlich im Moment gesetzt. Als Ergebnis erhalte ich aber LTIME = UTC. Ist nach der Deklaration in der LIB meines Erachtens nach auch logisch. Oder habe ich da einen Denkfehler.

tmp := time_zone_offset * 60 - BOOL_TO_INT(DST)*3600; /** In Deutschland 60 min Offset - 60 min DST ergibt doch 0, laut der Beschreibung müsste aber -120 rauskommen, oder???? Müsste der Offset nicht eine negative Zahl sein??

Vielen Dank im Voraus.

peewit

#1
Hallo Terminator95

Dein Problem mit LTIME_TO_UTC kann ich nachvollziehen !

Ich habe dir eine korrigierte version erstellt !

die alte hat nicht nur falsch gerechnet, sondern hat auch bei "DST" = True , das ganze jahr über die +1 Stunde für Sommerzeit mitgerechnet
die neue version prüft vorher ob bei LTIME überhaupt sommerzeit aktiv ist

und nicht vergessen time_offset wird in minuten angegeben

FUNCTION LTIME_TO_UTC : DT
VAR_INPUT
LTIME : DT;
DST_ENABLE : BOOL;
TIME_ZONE_OFFSET : INT;
END_VAR
VAR
tmp: INT;
tmp2: DWORD;
END_VAR

tmp := time_zone_offset * 60;
tmp2 := BOOL_TO_DWORD(DST_ENABLE AND DST(LTIME)) * 3600;
IF tmp < 0 THEN
tmp := ABS(tmp);
LTIME_TO_UTC := DWORD_TO_DT(DT_TO_DWORD(Ltime) + INT_TO_DWORD(tmp) - tmp2);
ELSE
LTIME_TO_UTC := DWORD_TO_DT(DT_TO_DWORD(Ltime) - INT_TO_DWORD(tmp) - tmp2);
END_IF;


Hallo,

ich hab noch was zum Thema beizurtagen, auch wenn es schon etwas älter ist. Hatte nämlich eben selbiges Problem:

Wozu der Aufwand, den halben Baustein umzuschreiben? Eigentlich hätte es doch gereicht in der ersten Zeile das Minus durch ein Plus zu ersetzen, so dass es so aussieht
Code:

tmp := time_zone_offset * 60 + BOOL_TO_INT(DST)*3600;

Habs gerade ausprobiert, sollte  auch funktionieren. Jetzt werden nämlich im Sommer richtigerweise 2h und im Winter 1h von der Systemzeit abgezogen (wenn man sich in Deutschland befindet).

Wär natürlich klasse, wenn es in der nächsten Release aufgenommen wird. Ich vermute, es ist in der 3.10 schlicht vergessen worden Wink

Gruß
Thomas

Terminator95

super, vielen Dank. Jetzt habe ich nur noch das Problem, dass Codesys auf einmal den Baustein DST als nicht gültigen Baustein anmeckert. Wie kriege ich das jetzt wieder hingebogen? Ich glaube, ich muss mich mal tiefer mit dem Ganzen auseinandersetzen. CFC reicht irgendwann nicht mehr. :-)

peewit

bei der neuen version hat sich auch ein input-parameter geändert, normalerweise reicht es wenn du den baustein neu in dein programm einfügst
oder du machst dir eine LTIME_TO_UTC_2 die du dann verwendest, bis die nächste oscat-release erscheint

neuen baustein "LTIME_TO_UTC_2" anlegen und diesen code verwenden

FUNCTION LTIME_TO_UTC_2 : DT
VAR_INPUT
   LTIME : DT;
   DST_ENABLE : BOOL;
   TIME_ZONE_OFFSET : INT;
END_VAR
VAR
   tmp: INT;
   tmp2: DWORD;
END_VAR

tmp := time_zone_offset * 60;
tmp2 := BOOL_TO_DWORD(DST_ENABLE AND DST(LTIME)) * 3600;
IF tmp < 0 THEN
   tmp := ABS(tmp);
   LTIME_TO_UTC_2 := DWORD_TO_DT(DT_TO_DWORD(Ltime) + INT_TO_DWORD(tmp) - tmp2);
ELSE
   LTIME_TO_UTC_2 := DWORD_TO_DT(DT_TO_DWORD(Ltime) - INT_TO_DWORD(tmp) - tmp2);
END_IF;

Terminator95

#4
Hallo Peewitt,

der Baustein an sich funktioniert schon. Auch die Inputparameter, aber der Baustein DST aus der OSCAT (den du ja auch für die Überprüfung verwendest) (AND DST(LTIME)) wird nicht mehr erkannt. Hast Du eine Idee woran das liegen kann??

**********************************
ich trottel, hatte wg. dem tollen Bug mit der Bausteinbegrenzung "alle unbenutzten" Bausteine beim Übersetzen ausgeschlossen. Darum fand Codesys natürlich den DST-Baustein nicht, da vorher nicht verwendet.

Danke.

D-Platoon

#5
Hallo,

ich hab noch was zum Thema beizurtagen, auch wenn es schon etwas älter ist. Hatte nämlich eben selbiges Problem:

Wozu der Aufwand, den halben Baustein umzuschreiben? Eigentlich hätte es doch gereicht in der ersten Zeile das Minus durch ein Plus zu ersetzen, so dass es so aussieht
tmp := time_zone_offset * 60 + BOOL_TO_INT(DST)*3600;
Habs gerade ausprobiert, sollte  auch funktionieren. Jetzt werden nämlich im Sommer richtigerweise 2h und im Winter 1h von der Systemzeit abgezogen (wenn man sich in Deutschland befindet).

Wär natürlich klasse, wenn es in der nächsten Release aufgenommen wird. Ich vermute, es ist in der 3.10 schlicht vergessen worden ;)

Gruß
Thomas

hugo

DEN BUG WERDEN WIR NATÜRLICH VERBESSERN.

aber sinnvoller wäre es in deinem fall die interne uhr auf utc laufen zu lassen und gegebenenfalls daraus die lokalzeit zu berechnen.
das ist immer eindeutig, logischer und weniger aufwendig