Time zones and DST

Does anyone have any suggestions on how to handle timezone and DST adjustments when you have a device that displays local time to the user through the UI?

Setting the time isn’t a problem as it can be done through the UI or SNTP. In my application, the internal time needs to be stored as UTC. The Time Zone issue comes into play primarily when the user is looking at the UI. The UI needs to display the correct local time.

Does anyone have any suggestions on how to handle the setup of the correct Time Zone?

Do you store and list all the time zones for the user to select? Or list just the common UTC offsets?
How about automatically adjusting for daylight saving time?

Any suggestions would be helpful.

Hi,
I used this adaption of TimeService: -GitHub - RoSchmi/TimeService_TinyCLR_Example: TimeService for TinyCLR

In any way the device must know in which timezone it actually is located and how the DST settings for this timezone is.

I ran into this a while back, RoSchmi is right though in that you must know the location/time zone before hand. My solution, in the U.S. at least, was to find the second Sunday of March and first Sunday of November…not exactly complex :sweat_smile: but it works reliably. I also created an enum with different time zones to add/subtract from UTC. Here is a slightly reduced version of my function:

    ///<summary> Internally calculates the daylight savings time and adjusts the RTC as needed. </summary>
    private static void CalculateDaylightSavings()
    {
        //Don't calculate DST if it is not applied in the current time zone
        if (!_useDst)
        {
            return;
        }

        //Pull the year component from the RTC
        int calculatedYear = _rtcController.Now.Year;

        do
        {
            //First find the DST start date - second Sunday of March
            _dstStartDate = new DateTime(calculatedYear, 3, 8, 2, 0, 0);

            while (_dstStartDate.DayOfWeek != DayOfWeek.Sunday)
            {
                _dstStartDate = _dstStartDate.AddDays(1);
            }

            //Then find the DST end date - first Sunday of November
            _dstEndDate = new DateTime(calculatedYear, 11, 1, 2, 0, 0);

            while (_dstEndDate.DayOfWeek != DayOfWeek.Sunday)
            {
                _dstEndDate = _dstEndDate.AddDays(1);
            }

            calculatedYear++;

        } while (_rtcController.Now >= _dstEndDate);

        Logger.LogMessage(Logger.Level.Debug, ControllerId, $"DST start date set to: {_dstStartDate.Date.ToString().Substring(0, 10)}");
        Logger.LogMessage(Logger.Level.Debug, ControllerId, $"DST end date set to: {_dstEndDate.Date.ToString().Substring(0, 10)}");

        //If the current time is during daylight savings
        if (!_dstIsActive && _rtcController.Now >= _dstStartDate && _rtcController.Now < _dstEndDate)
        {
            Logger.LogMessage(Logger.Level.Warning, ControllerId, "Daylight savings is now active.");
            _rtcController.Now = _rtcController.Now.AddHours(1);
            _dstIsActive = true;
        }

        //If the current time is not during daylight savings
        else if (_dstIsActive)
        {
            Logger.LogMessage(Logger.Level.Warning, ControllerId, "Daylight savings is now inactive.");
            _rtcController.Now = _rtcController.Now.AddHours(-1);
            _dstIsActive = false;
        }
    }

EDIT: Note that DST executes at 2am, so I have a timer that recalculates the time at 2am every day.

Thanks all for the input.

@willcopper12, the code you posted is helpful.

I guess the issue I am working through is how to store all the time zones, their offsets, and the date/time when DST is active. This is an international product so it has to support almost all of the potential time zones. The IANA time zone database is quite large.

Yep! It’s annoying and way over complicated…

1 Like