Блоки для Concept на EFB Toolkit.
Работает только в текущем веке!
Код: Выделить всё
///////////////////////////////////////////////////////////////////////////////
//Конвертация времени формата МЭК (по Гринвичу) в формат Concept (по Москве)
static BOOL TimeConvert_IEC_GMT_to_Concept_MSK(
PTR_UDINT T_IEC, //Время в формате МЭК
PTR_WORD YEAR, //Год
PTR_aWORD_1x8 Calend) //Дата
{
UINT i;
UINT days;
UINT days_add;
UINT days_in_month;
UINT ColichVisGod;
UINT PoslVoskrMarta;
UINT PoslVoskrOktyabrya;
UDINT ostatok;
UDINT T_IEC_MSK;
UDINT PoslVoskrMarta02_00;
UDINT PoslVoskrOkt02_00;
int arYDays [12];
arYDays [0] = 0;
arYDays [1] = 31;
arYDays [2] = 59;
arYDays [3] = 90;
arYDays [4] = 120;
arYDays [5] = 151;
arYDays [6] = 181;
arYDays [7] = 212;
arYDays [8] = 243;
arYDays [9] = 273;
arYDays [10] = 304;
arYDays [11] = 334;
//MSK = GMT+3
T_IEC_MSK = (* T_IEC)+3*MS100_PER_SEC*SECS_PER_HOUR;
//Високосный год
if ((* YEAR & 3) == 0)
days_add = 1;
else
days_add = 0;
//Определяем ситуацию, когда в москве уже новый год, а по гринвичу нет
if (T_IEC_MSK>=((365+days_add)*MS100_PER_SEC*SECS_PER_DAY))
{
(*Calend)[Calend_Year] = * YEAR+1;
T_IEC_MSK -= ((UDINT)(365+days_add))*MS100_PER_SEC*SECS_PER_DAY;
if (((* YEAR+1) & 3) == 0)
days_add = 1;
else
days_add = 0;
}
else
{
(*Calend)[Calend_Year] = * YEAR;
}
//Переход на летнее время
ColichVisGod=((*Calend)[Calend_Year]-1)/4;
PoslVoskrMarta=90-((*Calend)[Calend_Year]+ColichVisGod+5)%7;
if ((((*Calend)[Calend_Year]+4)%28)==0) PoslVoskrMarta+=7;
PoslVoskrOktyabrya=304-((*Calend)[Calend_Year]+ColichVisGod+2)%7;
if ((((*Calend)[Calend_Year]+24)%28)==0) PoslVoskrOktyabrya+=7;
PoslVoskrMarta02_00=((UDINT)(PoslVoskrMarta-1))*MS100_PER_SEC*SECS_PER_DAY+2*MS100_PER_SEC*SECS_PER_HOUR;
PoslVoskrOkt02_00=((UDINT)(PoslVoskrOktyabrya-1))*MS100_PER_SEC*SECS_PER_DAY+2*MS100_PER_SEC*SECS_PER_HOUR;
if (PoslVoskrMarta02_00<T_IEC_MSK && T_IEC_MSK<PoslVoskrOkt02_00) T_IEC_MSK += 1*MS100_PER_SEC*SECS_PER_HOUR;
//Месяц
days = T_IEC_MSK/MS100_PER_SEC/SECS_PER_DAY;
for (i = 0; i <= 10; i++)
{
days_in_month = arYDays [i + 1] - 1;
if (i > 1)
days_in_month = days_in_month + days_add;
if ( days <= days_in_month)
break;
}
(*Calend)[Calend_Month] = i + 1;
//День
days_in_month = arYDays [i];
if (i > 1)
days_in_month = days_in_month + days_add;
(*Calend)[Calend_Day] = days + 1 - days_in_month;
ostatok = T_IEC_MSK / MS100_PER_SEC - (days * SECS_PER_DAY);
//Час
(*Calend)[Calend_Hour] = ostatok/SECS_PER_HOUR;
ostatok = ostatok - (*Calend)[Calend_Hour] * SECS_PER_HOUR;
//Минуты
(*Calend)[Calend_Min] = ostatok/SECS_PER_MIN;
ostatok = ostatok - (*Calend)[Calend_Min] * SECS_PER_MIN;
//Секунды
(*Calend)[Calend_Sec] = ostatok;
return TRUE;
}
Работает только в текущем веке!
Код: Выделить всё
IF (CM_stat.Stat & CM_Stat_time_master) = CM_Stat_time_master THEN
(*Получена установка времени от мастера *)
New_Time := TRUE;
(*Конвертация времени формата МЭК (по Гринвичу) в формат Concept (по Москве)*)
(*MSK = GMT+3*)
T_IEC_MSK := IEC_Time+3*MS100_PER_SEC*SECS_PER_HOUR;
(*Високосный год*)
IF (INT_TO_WORD(BCD_TO_INT(WORD_TO_INT(INT_TO_WORD(%SW53) AND 16#00FF))) & 3) = 0 THEN
days_add := 1;
ELSE
days_add := 0;
END_IF;
Calend_Year := INT_TO_UINT(BCD_TO_INT(WORD_TO_INT(INT_TO_WORD(%SW53) AND 16#00FF)));
(*Определяем ситуацию, когда в москве уже новый год, а по гринвичу нет*)
IF T_IEC_MSK>=(UINT_TO_UDINT(365+days_add)*MS100_PER_SEC*SECS_PER_DAY) THEN
IF BCD_TO_INT(WORD_TO_INT(SHR_WORD (IN := INT_TO_WORD(%SW52) AND 16#FF00, N := 8))) = 12 THEN
Calend_Year := Calend_Year +1;
END_IF;
T_IEC_MSK := T_IEC_MSK -(UINT_TO_UDINT(365+days_add))*MS100_PER_SEC*SECS_PER_DAY;
IF (INT_TO_WORD(BCD_TO_INT(WORD_TO_INT(INT_TO_WORD(%SW53) AND 16#00FF))) & 3) = 0 THEN
days_add := 1;
ELSE
days_add := 0;
END_IF;
END_IF;
(*Переход на летнее время*)
ColichVisGod:=(Calend_Year-1)/4;
PoslVoskrMarta:=90-MOD (IN1 := (Calend_Year+ColichVisGod+5),IN2 := 7);
IF (MOD(IN1 :=Calend_Year+4,IN2 :=28))=0 THEN
PoslVoskrMarta:=PoslVoskrMarta+7;
END_IF;
PoslVoskrOktyabrya:=304-MOD(IN1 :=Calend_Year+ColichVisGod+2,IN2 :=7);
IF MOD(IN1 :=Calend_Year+24,IN2 :=28)=0 THEN
PoslVoskrOktyabrya:=PoslVoskrOktyabrya+7;
END_IF;
PoslVoskrMarta02_00:=(UINT_TO_UDINT(PoslVoskrMarta-1))*MS100_PER_SEC*SECS_PER_DAY+2*MS100_PER_SEC*SECS_PER_HOUR;
PoslVoskrOkt02_00:=(UINT_TO_UDINT(PoslVoskrOktyabrya-1))*MS100_PER_SEC*SECS_PER_DAY+2*MS100_PER_SEC*SECS_PER_HOUR;
IF PoslVoskrMarta02_00<T_IEC_MSK & T_IEC_MSK<PoslVoskrOkt02_00 THEN
T_IEC_MSK := T_IEC_MSK +1*MS100_PER_SEC*SECS_PER_HOUR;
END_IF;
(*Месяц*)
days := UDINT_TO_UINT(T_IEC_MSK/MS100_PER_SEC/SECS_PER_DAY);
FOR i := 0 TO 10 DO
days_in_month := arYDays [i + 1] - 1;
IF i > 1 THEN
days_in_month := days_in_month + days_add;
END_IF;
IF days <= days_in_month THEN
EXIT;
END_IF;
END_FOR;
Calend_Month:= i + 1;
(*День*)
days_in_month := arYDays [i];
if i > 1 THEN
days_in_month := days_in_month + days_add;
END_IF;
Calend_Day:= days + 1 - days_in_month;
ostatok := T_IEC_MSK / MS100_PER_SEC - (UINT_TO_UDINT(days) * SECS_PER_DAY);
(*Час*)
Calend_Hour:= UDINT_TO_UINT(ostatok/SECS_PER_HOUR);
ostatok := ostatok - UINT_TO_UDINT(Calend_Hour) * SECS_PER_HOUR;
(*Минуты*)
Calend_Min:= UDINT_TO_UINT(ostatok/SECS_PER_MIN);
ostatok := ostatok - UINT_TO_UDINT(Calend_Min) * SECS_PER_MIN;
(*Секунды*)
Calend_Sec:= UDINT_TO_UINT(ostatok);
New_Time_C[1] := WORD_TO_UINT(BYTE_AS_WORD (LOW := UINT_TO_BYTE(Calend_Year),HIGH := UINT_TO_BYTE(Calend_Month)));
New_Time_C[2] := WORD_TO_UINT(BYTE_AS_WORD (LOW := UINT_TO_BYTE(Calend_Day),HIGH := UINT_TO_BYTE(Calend_Hour)));
New_Time_C[3] := WORD_TO_UINT(BYTE_AS_WORD (LOW := UINT_TO_BYTE(Calend_Min),HIGH := UINT_TO_BYTE(Calend_Sec)));
END_IF;