How Can We Help?
How to automatically manage daylight saving time in the HMI using a macro?
In this post, we will show you how to automatically manage daylight saving time in the HMI using a macro. The time change was first applied in 1916. Since 2002, the time change has been carried out in a uniform manner in all the Member States of the European Union:
- the changeover to summer time takes place on the night of the last Saturday in March
- the changeover to winter time takes place on the night of the last Saturday in October

As a reminder, the EU countries are currently divided into three time zones:
- Western Europe (GMT): Ireland and Portugal
- Central Europe (GMT+1): Austria, Belgium, Croatia, Czech Republic, Denmark, France, Germany, Hungary, Italy, Luxembourg, Malta, Netherlands, Poland, Slovakia, Slovenia, Spain and Sweden
- Eastern Europe (GMT+2): Bulgaria, Cyprus, Estonia, Finland, Greece, Latvia, Lithuania and Romania.
With HMI-Tool

In the Macro Editor, add a new macro and copy it.
#include "MacroInit.h"
// Utility function: returns the number of days in a given month/year
int DaysInMonth(int month, int year)
{
switch(month)
{
case 1: return 31; // January
case 2: // February (check leap year)
if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0))
return 29;
else
return 28;
case 3: return 31; // March
case 4: return 30; // April
case 5: return 31; // May
case 6: return 30; // June
case 7: return 31; // July
case 8: return 31; // August
case 9: return 30; // September
case 10: return 31; // October
case 11: return 30; // November
case 12: return 31; // December
default: return 30; // fallback
}
}
void Macro_main(IN *p)
{
MarcoInit
// Automatic Daylight Saving Time (DST) / Winter Time switching
// This function must be called every minute
int minute = BCD2BIN(LocalWord[60001]); // Current minute (BCD → decimal)
int hour = BCD2BIN(LocalWord[60002]); // Current hour
int day = BCD2BIN(LocalWord[60003]); // Day of month
int month = BCD2BIN(LocalWord[60004]); // Month
int year = BCD2BIN(LocalWord[60005]); // Year
int dayOfWeek = BCD2BIN(LocalWord[60006]); // Monday=1 ... Sunday=7
int daysInMonth = DaysInMonth(month, year);
// --- Switch to Summer Time (DST) ---
// Condition: Last Sunday of March at 03:00 → clock jumps to 04:00
if ((month == 3) && (dayOfWeek == 7) && (day + 7 > daysInMonth) && (hour == 3) && (minute == 0))
{
LocalWord[60002] = 4; // Set hour = 04
LocalBit[65535] = 0; // Flag = Summer Time
}
// --- Switch to Winter Time ---
// Condition: Last Sunday of October at 03:00 → clock goes back to 02:00
if ((LocalBit[65535] == 0) && (month == 10) && (dayOfWeek == 7) && (day + 7 > daysInMonth) && (hour == 3) && (minute == 0))
{
LocalWord[60002] = 2; // Set hour = 02
LocalBit[65535] = 1; // Flag = Winter Time (prevents infinite loop)
}
}
Add the macro in “global Macro” list And set its execution frequency to 60000 ms (1 minute) to update the clock every minute.

How it works
The program runs every minute and reads the current time (minute, hour, day, month, year, weekday) from registers.
All time values are stored in BCD format, so they are first converted to decimal.
A helper function computes the number of days in the current month, including leap years.
To detect the last Sunday of the month, the code checks: dayOfWeek == 7 (Sunday) and day + 7 > daysInMonth.
If it is the last Sunday of March at exactly 03:00, the clock is advanced to 04:00 (Daylight Saving Time).
A flag bit (LocalBit[65535]) is set to indicate summer time.
If it is the last Sunday of October at exactly 03:00, the clock is moved back to 02:00 (Winter Time).
The flag bit is switched to indicate winter time, preventing repeated corrections.
This avoids infinite loops where the same hour would be processed multiple times.
The system therefore keeps local time synchronized with official DST rules automatically.
You can replace LB65535 by LB51999 for backup the value (HMI register types: LB, LW, RWI and retentive/save register)
See also How to set and synchronize the ACE PLC clock with the HMI using a macro