前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >读取PLC时间转换为UNIX 时间做网络同步比较

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

作者头像
剑指工控
发布2021-11-09 14:58:16
1.1K0
发布2021-11-09 14:58:16
举报
文章被收录于专栏:剑指工控

JZGKCHINA

工控技术分享平台

最近在安全行业里做读取PLC内部故障事件分析的工作,发现在PLC网络里采用NTP时间同步基本上没有,因为在工控领域PLC更多承担业务层面控制需求的实现,反而对于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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 剑指工控 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档