之前我们分享了如何实现将DTL格式的日期时间转换为字符串,可直接封装成FC块供重复使用。
本次程序以实际生产中维护保养模块需求,实现维护保养自动生成结束时间,及当前设备保养状态,周期可根据需求自由选择按年、月、日、时、分自由选择;可直接应用于上位机、触摸屏等,HMI实现效果如下图:
image-20240401171347174
Step1:将当前时间实时转为string格式(已封装标准FC可重复使用)
REGION 将当前时间DTL实时转化为String
"C602_DateTime_DTL_To_String"(DateTime_DTL := #DateTime_Now_DTL,
DateTime_String => #DateTime_Now_String);
END_REGION
Step2:当模式不=0时,为开始时间和结束时间赋初值
REGION 当模式不=0时,为开始时间和结束时间赋初值;
IF #SelectMode <> 0 THEN
// 初始化,通过初始化状态ONS[0]判断;
IF #ONS[0] = FALSE THEN
// 将当前时间Move给维护开始时间(开始时间只有在维护确认后,才可以重新赋值)
#Start_DateTime := #DateTime_Now_String;
#Start_DateTime_DTL := #DateTime_Now_DTL;
// 初始化完成
#ONS[0] := TRUE;
END_IF;
ELSE
// 当SelectMode==0时,开始时间,输出时间都为空; 此处用空格代替;
#Start_DateTime := ' ';
#End_DateTime := ' ';
#ONS[0] := FALSE;
END_IF;
END_REGION
Step3:根据选择模式,计算直接累加后的结束时间
REGION 根据选择模式,计算直接累加后的结束时间
CASE #SelectMode OF
1:
#End_DateTime_INT.YEAR := #Start_DateTime_DTL.YEAR + #DataSet;
#End_DateTime_INT.MONTH := #Start_DateTime_DTL.MONTH;
#End_DateTime_INT.DAY := #Start_DateTime_DTL.DAY;
#End_DateTime_INT.HOUR := #Start_DateTime_DTL.HOUR;
#End_DateTime_INT.MINUTE := #Start_DateTime_DTL.MINUTE;
#End_DateTime_INT.SECOND := #Start_DateTime_DTL.SECOND;
2:
#End_DateTime_INT.YEAR := #Start_DateTime_DTL.YEAR;
#End_DateTime_INT.MONTH := #Start_DateTime_DTL.MONTH + #DataSet;
#End_DateTime_INT.DAY := #Start_DateTime_DTL.DAY;
#End_DateTime_INT.HOUR := #Start_DateTime_DTL.HOUR;
#End_DateTime_INT.MINUTE := #Start_DateTime_DTL.MINUTE;
#End_DateTime_INT.SECOND := #Start_DateTime_DTL.SECOND;
3:
#End_DateTime_INT.YEAR := #Start_DateTime_DTL.YEAR;
#End_DateTime_INT.MONTH := #Start_DateTime_DTL.MONTH;
#End_DateTime_INT.DAY := #Start_DateTime_DTL.DAY + #DataSet;
#End_DateTime_INT.HOUR := #Start_DateTime_DTL.HOUR;
#End_DateTime_INT.MINUTE := #Start_DateTime_DTL.MINUTE;
#End_DateTime_INT.SECOND := #Start_DateTime_DTL.SECOND;
4:
#End_DateTime_INT.YEAR := #Start_DateTime_DTL.YEAR;
#End_DateTime_INT.MONTH := #Start_DateTime_DTL.MONTH;
#End_DateTime_INT.DAY := #Start_DateTime_DTL.DAY;
#End_DateTime_INT.HOUR := #Start_DateTime_DTL.HOUR + #DataSet;
#End_DateTime_INT.MINUTE := #Start_DateTime_DTL.MINUTE;
#End_DateTime_INT.SECOND := #Start_DateTime_DTL.SECOND;
5:
#End_DateTime_INT.YEAR := #Start_DateTime_DTL.YEAR;
#End_DateTime_INT.MONTH := #Start_DateTime_DTL.MONTH;
#End_DateTime_INT.DAY := #Start_DateTime_DTL.DAY;
#End_DateTime_INT.HOUR := #Start_DateTime_DTL.HOUR;
#End_DateTime_INT.MINUTE := #Start_DateTime_DTL.MINUTE + #DataSet;
#End_DateTime_INT.SECOND := #Start_DateTime_DTL.SECOND;
END_CASE;
END_REGION
Step4:对累加后的数据进行处理
REGION 对累加后的数据进行处理
// 判断分钟是否超过60分钟,如果超过则小时+1,分钟数-60
IF #End_DateTime_INT.MINUTE >= 60 THEN
#End_DateTime_INT.HOUR := #End_DateTime_INT.HOUR + TRUNC(#End_DateTime_INT.MINUTE / 60);
#End_DateTime_INT.MINUTE := #End_DateTime_INT.MINUTE - TRUNC(#End_DateTime_INT.MINUTE / 60) * 60;
END_IF;
// 判断小时是否超过24小时,如果超过则日+1,分钟数-24
IF #End_DateTime_INT.HOUR >= 24 THEN
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY + TRUNC(#End_DateTime_INT.HOUR / 24);
#End_DateTime_INT.HOUR := #End_DateTime_INT.HOUR - TRUNC(#End_DateTime_INT.HOUR / 24) * 24;
END_IF;
WHILE #SelectMode <> 0 DO
REGION 对“日”进行处理,由于日处理,牵扯到每月多少天,包括2月,润年等,所以需要使用循环处理
CASE #End_DateTime_INT.MONTH OF
1:
IF #End_DateTime_INT.DAY > 31 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
END_IF;
2:
IF (#End_DateTime_INT.YEAR - TRUNC(#End_DateTime_INT.YEAR / 4) * 4) = 0 THEN
IF #End_DateTime_INT.DAY > 29 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 29;
END_IF;
ELSE
IF #End_DateTime_INT.DAY > 28 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 28;
END_IF;
END_IF;
3:
IF #End_DateTime_INT.DAY > 31 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
END_IF;
4:
IF #End_DateTime_INT.DAY > 30 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 30;
END_IF;
5:
IF #End_DateTime_INT.DAY > 31 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
END_IF;
6:
IF #End_DateTime_INT.DAY > 30 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 30;
END_IF;
7:
IF #End_DateTime_INT.DAY > 31 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
END_IF;
8:
IF #End_DateTime_INT.DAY > 31 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
END_IF;
9:
IF #End_DateTime_INT.DAY > 30 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 30;
END_IF;
10:
IF #End_DateTime_INT.DAY > 31 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
END_IF;
11:
IF #End_DateTime_INT.DAY > 30 THEN
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 30;
END_IF;
12:
IF #End_DateTime_INT.DAY > 31 THEN
#End_DateTime_INT.MONTH := 1;
#End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
END_IF;
END_CASE;
END_REGION
REGION 对月份进行处理
IF #End_DateTime_INT.MONTH > 12 THEN
#End_DateTime_INT.YEAR := #End_DateTime_INT.YEAR + 1;
#End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH - 12;
END_IF;
END_REGION
REGION 对处理结果进行判断,处理完毕则跳出循环;
IF #End_DateTime_INT.MONTH = 1
OR #End_DateTime_INT.MONTH = 3
OR #End_DateTime_INT.MONTH = 5
OR #End_DateTime_INT.MONTH = 7
OR #End_DateTime_INT.MONTH = 8
OR #End_DateTime_INT.MONTH = 10
OR #End_DateTime_INT.MONTH = 12 THEN
IF #End_DateTime_INT.DAY <= 31 THEN
EXIT;
END_IF;
END_IF;
IF #End_DateTime_INT.MONTH = 4
OR #End_DateTime_INT.MONTH = 6
OR #End_DateTime_INT.MONTH = 9
OR #End_DateTime_INT.MONTH = 11
OR #End_DateTime_INT.MONTH = 10
OR #End_DateTime_INT.MONTH = 12 THEN
IF #End_DateTime_INT.DAY <= 30 THEN
EXIT;
END_IF;
END_IF;
IF #End_DateTime_INT.MONTH = 2 THEN
IF (#End_DateTime_INT.YEAR - TRUNC(#End_DateTime_INT.YEAR / 4) * 4) = 0 THEN
IF #End_DateTime_INT.DAY <= 29 THEN
EXIT;
END_IF;
ELSE
IF #End_DateTime_INT.DAY <= 28 THEN
EXIT;
END_IF;
END_IF;
END_IF;
END_REGION
END_WHILE;
END_REGION
Step5:将处理后的累加值发送Move给结束时间DTL,将结束时间DTL转化为String
REGION 将处理后的累加值发送Move给结束时间DTL,将结束时间DTL转化为String
#End_DateTime_DTL.YEAR := #End_DateTime_INT.YEAR;
#End_DateTime_DTL.MONTH := #End_DateTime_INT.MONTH;
#End_DateTime_DTL.DAY := #End_DateTime_INT.DAY;
#End_DateTime_DTL.HOUR := #End_DateTime_INT.HOUR;
#End_DateTime_DTL.MINUTE := #End_DateTime_INT.MINUTE;
#End_DateTime_DTL.SECOND := #End_DateTime_INT.SECOND;
IF #SelectMode <> 0 THEN
"C602_DateTime_DTL_To_String"(DateTime_DTL := #End_DateTime_DTL,
DateTime_String => #End_DateTime);
ELSE
#End_DateTime := ' ';
END_IF;
END_REGION
Step6:比较当前日期时间与结束日期时间,判断当前状态
REGION 判断状态
IF #SelectMode = 0 THEN
#Status := 0;
ELSE
IF #DateTime_Now_DTL.YEAR > #End_DateTime_DTL.YEAR THEN
#Status := 2;
ELSIF #DateTime_Now_DTL.YEAR < #End_DateTime_DTL.YEAR THEN
#Status := 1;
ELSIF #DateTime_Now_DTL.YEAR = #End_DateTime_DTL.YEAR THEN
IF #DateTime_Now_DTL.MONTH > #End_DateTime_DTL.MONTH THEN
#Status := 2;
ELSIF #DateTime_Now_DTL.MONTH < #End_DateTime_DTL.MONTH THEN
#Status := 1;
ELSIF #DateTime_Now_DTL.MONTH = #End_DateTime_DTL.MONTH THEN
IF #DateTime_Now_DTL.DAY > #End_DateTime_DTL.DAY THEN
#Status := 2;
ELSIF #DateTime_Now_DTL.DAY < #End_DateTime_DTL.DAY THEN
#Status := 1;
ELSIF #DateTime_Now_DTL.DAY = #End_DateTime_DTL.DAY THEN
IF #DateTime_Now_DTL.HOUR > #End_DateTime_DTL.HOUR THEN
#Status := 2;
ELSIF #DateTime_Now_DTL.HOUR < #End_DateTime_DTL.HOUR THEN
#Status := 1;
ELSIF #DateTime_Now_DTL.HOUR = #End_DateTime_DTL.HOUR THEN
IF #DateTime_Now_DTL.MINUTE > #End_DateTime_DTL.MINUTE THEN
#Status := 2;
ELSIF #DateTime_Now_DTL.MINUTE < #End_DateTime_DTL.MINUTE THEN
#Status := 1;
ELSIF #DateTime_Now_DTL.MINUTE = #End_DateTime_DTL.MINUTE THEN
IF #DateTime_Now_DTL.SECOND > #End_DateTime_DTL.SECOND THEN
#Status := 2;
ELSIF #DateTime_Now_DTL.SECOND < #End_DateTime_DTL.SECOND THEN
#Status := 1;
END_IF;
END_IF;
END_IF;
END_IF;
END_IF;
END_IF;
END_IF;
END_REGION
|