关键是使用FB_TzSpecificLocalTimeToFileTime使用当前时区信息 ( ST_TimeZoneInformation )将当前T_FILETIME 转换为 UTC 。这将为您提供一个 UTC windows 文件时间(滴答声),需要将其转换为 UTC unix 时间。
这是此过程的功能块实现:
宣言
FUNCTION_BLOCK UnixTimestamp
VAR_OUTPUT
seconds: ULINT;
milliseconds: ULINT;
END_VAR
VAR
localSystemTime : FB_LocalSystemTime := ( bEnable := TRUE, dwCycle := 1 );
getTimeZoneInformation : FB_GetTimeZoneInformation;
timeZoneInformation : ST_TimeZoneInformation;
specificLocalTimeToFileTime : FB_TzSpecificLocalTimeToFileTime;
fileTime: T_FILETIME;
onZerothSecondLastCycle : BOOL;
END_VAR
执行
// Get local system time
localSystemTime();
// On the zeroth second of each minutesync timezone information
IF (timeZoneInformation.standardName = '' OR (localSystemTime.systemTime.wSecond = 0 AND NOT onZerothSecondLastCycle)) THEN
getTimeZoneInformation(sNetID := '', bExecute := TRUE, tzInfo => timeZoneInformation);
END_IF;
// Convert local system time to unix timestamps
specificLocalTimeToFileTime(in := Tc2_Utilities.SYSTEMTIME_TO_FILETIME(localSystemTime.systemTime), tzInfo := timeZoneInformation, out => fileTime);
seconds := (SHL(DWORD_TO_ULINT(fileTime.dwHighDateTime), 32) + DWORD_TO_ULINT(fileTime.dwLowDateTime)) / 10000000 - 11644473600;
milliseconds := (SHL(DWORD_TO_ULINT(fileTime.dwHighDateTime), 32) + DWORD_TO_ULINT(fileTime.dwLowDateTime)) / 10000 - 11644473600000;
onZerothSecondLastCycle := localSystemTime.systemTime.wSecond = 0;
用法
VAR
unixTime: UnixTimestamp;
timestampSeconds: ULINT;
timestampMilliseconds: ULINT;
END_VAR
-----
unixTime();
timestampMilliseconds := unixTime.milliseconds;
timestampSeconds := unixTime.seconds;