2017-01-20 26 views
0

우리는 Beckhoff TwinCAT3에서 데이터 로깅 어플리케이션을 연구하고 있습니다. 우리가 현재 LTIME()를 사용하는 시간을 얻으려면, 다음 사용하여 MS에 C#으로 그 변환 :TwinCAT3에서 유닉스 타임 스탬프를 얻으려면 어떻게해야합니까?

ulong valA = reader.ReadUInt64(); // this gets the LTIME 
long ftime = (long)(valA/100); 
DateTime t = DateTime.FromFileTime(ftime); 
return (t.ToUniversalTime().Ticks - 621355968000000000)/10000; 

더 나은 방법이 있어야합니다. 또한이 시간과 컴퓨터 시간 (작업 표시 줄에있는 시간) 사이의 차이가 나타납니다.

컴퓨터 시계에서 1970 년 (GMT) 이후로 ms를 얻는 가장 좋은 방법은 무엇입니까?

나는 NT_GetTime을 참조하십시오. 우리가 구조체에 수학을 할 필요가있는 것처럼 보입니다.

어떤 포인터를 주셔서 감사합니다.

+0

중요한 점은 특히 데이터 포인트 간의 시간 간격이 매우 정확해야하는 경우 특히 PLC에서 시간을 해결하는 방법이 중요합니다. NT_GetTime 지터가/정확하지 않습니다. [Infosys] (https://infosys.beckhoff.com/content/1031/tcplclib_tc2_utilities/18014398544903307.html)를 참조하십시오. –

답변

0

키는 FB_TzSpecificLocalTimeToFileTime을 사용하여 현재 T_FILETIME을 현재 시간대 정보 (ST_TimeZoneInformation)를 사용하여 UTC로 변환합니다. 이것은 UTC unix 시간으로 커버해야하는 UTC 윈도우 파일 시간 (틱)입니다. 여기

이 과정의 기능 블록의 구현이다

선언

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;