加入收藏 | 设为首页 | 会员中心 | 我要投稿 上海站长网 (https://www.021zz.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

读取PLC时间转换为UNIX 时间做网络同步比较

发布时间:2022-12-07 13:35:48 所属栏目:Unix 来源:转载
导读: 最近在安全行业里做读取PLC内部故障事件分析的工作,发现在PLC网络里采用NTP时间同步基本上没有,因为在工控领域PLC更多承担业务层面控制需求的实现unix媒体转换,反而对于PLC本身的安全并

最近在安全行业里做读取PLC内部故障事件分析的工作,发现在PLC网络里采用NTP时间同步基本上没有,因为在工控领域PLC更多承担业务层面控制需求的实现unix媒体转换,反而对于PLC本身的安全并没有过多的重视。

多区域内PLC时间同步就是安全设置的必要一步,因为这个会涉及PLC内部的事件和记录是否能够按照真实的时间进行提取和分析。那在不同网段读取不同厂商PLC时间进行比较和同步就成为一个比较麻烦的事情。不同厂商PLC的日期和时间比较需要用到一个INT数组数据来比较。所以才有了这需求打算采用Unix 时间来做时间对比,因为所有厂商的PLC的日期和时间都可以转成Unix 时间。

先说一下什么是Unix 时间:Unix时间(英文为Unix epoch, Unix time, POSIX time 或 Unix timestamp) 是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。UNIX时间的0按照ISO 8601规范为 :1970-01-01T00:00:00Z. 一个小时表示为UNIX时间格式为:3600秒;一天表示为UNIX时间为86400秒,闰秒不计算。

时间 秒

1 分钟 60 秒

1 小时 3600 秒

1 天 86400 秒

1 周 604800 秒

1 月 (30.44 天) 2629743 秒

1 年 (365.24 天) 31556926 秒

下面我将采用结构化文本的形式来开发这个PLC时间转成Unix时间,为了方便大家在其他的PLC中实现时间格式的转换。

// Convert system time to unix time

// (seconds until 1970-01-01 00:00)

// Create by jiansiting

FUNCTION Unixtime : DWORD

VAR_INPUT

END_VAR

VAR_TEMP

leapyears: INT;

days_from_1970 : DINT;

days_from_BeginOfYear : ARRAY[1..12] OF INT;

l_unixtime: DINT;

sfc1_ret_val : INT;

CDT_systemtime : DATE_AND_TIME;

systemtime AT CDT_systemtime : STRUCT

year_CDT: BYTE; // 1970 ... 2038

month_CDT: BYTE;

day_CDT: BYTE;

hour_CDT: BYTE;

minute_CDT: BYTE;

second_CDT: BYTE;

END_STRUCT;

year: INT; // 1970 ... 2038

month: INT;

day: INT;

hour: INT;

minute: INT;

second: INT;

END_VAR

leapyears:= 0;

days_from_1970 := 0;

// days of current month without leap day

days_from_BeginOfYear[1] := 0;

days_from_BeginOfYear[2] := 31;

days_from_BeginOfYear[3] := 59;

days_from_BeginOfYear[4] := 90;

days_from_BeginOfYear[5] := 120;

days_from_BeginOfYear[6] := 151;

days_from_BeginOfYear[7] := 181;

days_from_BeginOfYear[8] := 212;

days_from_BeginOfYear[9] := 243;

days_from_BeginOfYear[10] := 273;

days_from_BeginOfYear[11] := 304;

days_from_BeginOfYear[12] := 334;

// read system time

sfc1_ret_val := READ_CLK(CDT := CDT_systemtime);

year:= BCD_TO_INT(systemtime.year_CDT) + 2000;

month:= BCD_TO_INT(systemtime.month_CDT);

day:= BCD_TO_INT(systemtime.day_CDT);

hour:= BCD_TO_INT(systemtime.hour_CDT);

minute:= BCD_TO_INT(systemtime.minute_CDT);

second:= BCD_TO_INT(systemtime.second_CDT);

// sum of leap years since 1979 (without current leap year)

leapyears := ((year-1)-1968)/4-((year-1)-1900)/100+((year-1)-1600)/400;

days_from_1970 := (year-1970)*365 + leapyears+ days_from_BeginOfYear[month] + day-1;

IF ( (month > 2) AND ((year MOD 4 = 0) AND ((year MOD 100 0) OR (year MOD 400 = 0))) ) THEN

days_from_1970 := days_from_1970 + 1; // + leap day, if year is leap year

END_IF;

// OUTPUT in s

l_unixtime := second + 60 * ( minute + 60 * (hour + 24 * days_from_1970) );

// if error return 0

IF sfc1_ret_val 0 THEN

Unixtime := 0;

ELSE

Unixtime := DINT_TO_DWORD(l_unixtime);

END_IF;

END_FUNCTION

(编辑:上海站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章