0

I need to convert the timestruct I get from Beckhoffs function block "FB_LocalSystemTime" to milliseconds since epoch to receive the local computer time in milliseconds.

Unfortunately I can't find a function to convert this timestruct. Any help is appreciated.

//Local Systemtime variables
fbTime : FB_LocalSystemTime := ( bEnable := TRUE, dwCycle := 1 );
timosmd
  • 159
  • 11

4 Answers4

2

I think you can use DT_TO_DINT after converting the TIMESTRUCT to DT. This should give you seconds since Jan 1, 1970.

EDIT: This code should give you milliseconds since 1/1/1970.

PROGRAM MAIN
VAR
    fbTime: FB_LocalSystemTime;
    tStruct: TIMESTRUCT;
    msec: DINT;
    dTime: DATE_AND_TIME;
    eTime_sec: DINT;
    eTime_msec: LINT;
END_VAR
fbTime(bEnable:=TRUE, dwCycle:=1, SystemTime=>tStruct);

msec := tStruct.wMilliseconds;
tStruct.wMilliseconds := 0;

dTime := SYSTEMTIME_TO_DT(tStruct);
eTime_sec := DT_TO_DINT(dTime);
eTime_msec := DINT_TO_LINT(eTime_sec) * 1000 + msec;
kolyur
  • 457
  • 2
  • 13
2

You will get miliseconds with this function:

FUNCTION F_SYSTEMTIME_TO_TIMESTRUCT : TIMESTRUCT
VAR
    fbGetSystemTime : GETSYSTEMTIME;    (*timestamp*)
    fileTime        : T_FILETIME;
    sDT: STRING(30);
END_VAR
fbGetSystemTime(timeLoDW => fileTime.dwLowDateTime, timeHiDW => fileTime.dwHighDateTime);
sDT := SYSTEMTIME_TO_STRING(FILETIME_TO_SYSTEMTIME(fileTime));

F_SYSTEMTIME_TO_TIMESTRUCT.wYear := STRING_TO_WORD(LEFT(sDt, 4));
F_SYSTEMTIME_TO_TIMESTRUCT.wMonth := STRING_TO_WORD(MID(sDt, 2, 6));
F_SYSTEMTIME_TO_TIMESTRUCT.wDay := STRING_TO_WORD(MID(sDt, 2, 9));
F_SYSTEMTIME_TO_TIMESTRUCT.wHour := STRING_TO_WORD(MID(sDt, 2, 12));
F_SYSTEMTIME_TO_TIMESTRUCT.wMinute := STRING_TO_WORD(MID(sDt, 2, 15));
F_SYSTEMTIME_TO_TIMESTRUCT.wSecond := STRING_TO_WORD(MID(sDt, 2, 18));
F_SYSTEMTIME_TO_TIMESTRUCT.wMilliseconds := STRING_TO_WORD(RIGHT(sDt, 3));
  • You can use [`SYSTEMTIME_TO_DT()`](https://infosys.beckhoff.com/english.php?content=../content/1033/tcplclibutilities/html/TcPlcLibUtilities_DT_TO_SYSTEMTIME.htm&id=) for this. – Roald Apr 20 '21 at 09:30
  • how do you get the miliseconds? The most significant digit for DT is one second – Daniel Müller Navarro Apr 21 '21 at 11:06
  • That is true. Sorry. Still you could use the `SYSTEMTIME_TO_DT` for all except the ms, right? That will save you a few lines. – Roald Apr 21 '21 at 12:21
0

You can use the SYSTEMTIME_TO_DT() function to convert a timestruct to dt which is a 4byte DATE_AND_TIME data type.

The smallest unit of this data type is a second though and not a millisecond. Given that TIMESTRUCT has a millisecond value in it, you can easily use it and concatenate everything to a human readable string.

Filippo Boido
  • 1,136
  • 7
  • 11
  • 1
    Just one (sometimes important) note: The `SYSTEMTIME_TO_DT` [rounds milliseconds to nearest second](https://infosys.beckhoff.com/content/1033/tcplclib_tc2_utilities/9007199289893899.html?id=6847227180317996074), which can cause something that you don't want. For example, if time is 17:52:10.600, the DT would be 17:52:11. But if you really think about it, it should be 17:52:10. This can be fixed by setting the `TIMESTRUCT` value `wMilliseconds` to 0 before conversion. – Quirzo Sep 15 '20 at 04:26
0

I've used function GetSystemTime() which returns number of 100ns since 1 January 1601 (god knows why). So we just need to shift up to 1/1/1970 by add 11644473600_000_000_0 (which is amount od 100ns periods between dates) and then convert 100ns periods to e.g. miliseconds by divide over 1000_0 or seconds by divide them over 1_000_000_0. Remember that's a UTC time, if You want to get local time use FB_LocalSystemTime and timestruct conversion as @kolyur mentioned.

FUNCTION GET_UNIX_EPOCH : ULINT
GET_UNIX_EPOCH := (F_GetSystemTime() - 116444736000000000) / 10000;