ST Unix Time
Aug 31, 22Простая задача. Есть Unix time в секундах, а нужно получить нормальную дату. Алгоритмы пересчета для простых языков программирования не подходят, так как самое максимальное число у нас в контроллере ограничено 32 битами. Что ж, гуглим примеры и находим очень хороший пример на С - Oryx embedded date_time.c File Reference.
Переделываем под нашу систему и получаем что-то тип такого:
<FBSource nameOfFBType="UnixConverter" version="0.01" dateTime="dt#2022-08-31-20:30:22">
<attribute name="TypeCodeCheckSumString" value="7CF8"></attribute>
<attribute name="TypeSignatureCheckSumString" value="BA3D"></attribute>
<inOutParameters>
<variables name="t" typeName="UDINT">
<attribute name="PositionPin" value="1"></attribute>
</variables>
</inOutParameters>
<outputParameters>
<variables name="DateAndTime" typeName="DATEandTIME">
<attribute name="PositionPin" value="2"></attribute>
</variables>
</outputParameters>
<privateLocalVariables>
<variables name="z" typeName="UDINT"></variables>
<variables name="era" typeName="INT"></variables>
<variables name="doe" typeName="UDINT"></variables>
<variables name="yoe" typeName="UDINT"></variables>
<variables name="y" typeName="UDINT"></variables>
<variables name="doy" typeName="UDINT"></variables>
<variables name="a" typeName="UDINT"></variables>
<variables name="b" typeName="UDINT"></variables>
<variables name="c" typeName="UDINT"></variables>
<variables name="d" typeName="UDINT"></variables>
<variables name="e" typeName="UDINT"></variables>
<variables name="f" typeName="UDINT"></variables>
<variables name="t0" typeName="UDINT"></variables>
<variables name="msk" typeName="UDINT"></variables>
</privateLocalVariables>
<FBProgram name="MAIN">
<STSource>
msk := 10800;
(*t0 := t + msk;*)
DateAndTime.second := UDINT_TO_INT(t mod 60);
t0 := t / 60;
DateAndTime.minute := UDINT_TO_INT(t0 mod 60);
t0 := t0 / 60;
DateAndTime.hour := UDINT_TO_INT(t0 mod 24);
t0 := t0 / 24;
(*Convert Unix time to date*)
a := (4 * t0 + 102032) / 146097 + 15;
b := (t0 + 2442113 + a - (a / 4));
c := (20 * b - 2442) / 7305;
d := b - 365 * c - (c / 4);
e := d * 1000 / 30601;
f := d - e * 30 - e * 601 / 1000;
(*
January and February are counted as months 13 and 14 of the previous year
*)
IF (e <= 13)
THEN
c := c - 4716;
e := e - 1;
ELSE
c := c - 4715;
e := e - 13;
END_IF;
DateAndTime.year := UDINT_TO_INT(c);
DateAndTime.month := UDINT_TO_INT(e);
DateAndTime.day := UDINT_TO_INT(f);
</STSource>
</FBProgram>
</FBSource>
<DDTSource DDTName="DATEandTIME" version="0.01" dateTime="dt#2022-09-01-20:24:08">
<attribute name="TypeSignatureCheckSumString" value="08CD"></attribute>
<structure>
<variables name="Year" typeName="INT"></variables>
<variables name="Month" typeName="INT"></variables>
<variables name="Day" typeName="INT"></variables>
<variables name="Hour" typeName="INT"></variables>
<variables name="Minute" typeName="INT"></variables>
<variables name="Second" typeName="INT"></variables>
</structure>
</DDTSource>
Готовый файл для импорта функции можно скачать по ссылке ниже: ST Unix Time Unity XL,