
Сообщение от
kondor3000
Просто сильно сократили, у меня получилось вычисление дня до начала года и дня до начала месяца, по 2 одинаковых строки, с разными условиями.
Наступил на те же грабли. Пока у себя проверял, набрался опыта )
Ну да, вот универсальный код (за исключением первой строчки)
Код:
// <Description>Извлечение даты и времени из формата UnixTime от 01.01.2000</Description>
/// <GroupName>Дата и время</GroupName>
function_block UDT_to_DateTime // от 01.01.2000
var_input
UDT: udint := 0; //дата и время в формате Unix от 01.01.2000 в секундах (если = 0, то берем системное время)
end_var
var_output
day: udint;
month: udint;
year: udint;
hour: udint;
min: udint;
sec: udint;
week: udint;
end_var
var
day_month: array [1..12] of udint := [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
uiDate, uiDay: udint;
days_to_year, days_to_month: udint;
is_leap_year: bool;
end_var
if UDT = 0 then UDT := dt_to_udint(get_date_time()); end_if;
//Общее количество дней
uiDate := UDT / 86400;
//Приблизительно определяем год
Year := uiDate / 365 + 2000;
//Количество дней от 01.01.2000 до начала года
days_to_year := (Year - 2000)*365 + (Year - 1997)/4 - (Year - 1901)/100 + (Year-1601)/400;
//Уточняем год
if uiDate < days_to_year then
Year := Year - 1;
days_to_year := (Year - 2000)*365 + (Year - 1997)/4 - (Year - 1901)/100 + (Year-1601)/400;
end_if
//Количество дней от начала года
uiDay := uiDate - days_to_year + 1;
//Приблизительно определяем месяц
month := uiDay / 29 + 1;
if month > 12 then month := 12; end_if
//Проверяем год на високосность
is_leap_year := (Year mod 400 = 0) or ((Year mod 4 = 0) and (Year mod 100 <> 0));
//Количество дней от нового года до начала месяца
days_to_month := day_month[month] + bool_to_udint(is_leap_year and Month > 2);
//Уточняем месяц
if uiDay <= days_to_month then
Month := Month - 1;
days_to_month := day_month[month] + bool_to_udint(is_leap_year and Month > 2);
end_if
//Находим день
Day := uiDay - days_to_month;
//Время
hour := (UDT / 3600) mod 24;
min := (UDT / 60) mod 60;
sec := UDT mod 60;
//День недели
week := ((UDT / 86400 + 6) mod 7);
if week = 0 then week := 7; end_if
end_function_block