Handling Time Zones and Daylight Savings Time in .NET Micro Framework 4.1

I'm going to write this up as I experiment. Forgive the meandering.

As per previous posts, I'm trying to implement a complete solution for time zones including daylight savings. I know I can't (without Internet access) use latitude, longitude and UTC time to determine the current time zone and daylight savings condition (see earthtools.org). So I have to concede I can only hard-code a limited set of time zones. For now I'm happy just to implement Australian Eastern Standard Time (AEST) and Australian Eastern Daylight Savings Time (AEDST).

My starting point is Jens Kühner's book Expert .NET Micro Framework (page 62). But when I try to use ExtendedTimeZone.SetTimeZone it's not recognized in Visual Studio. I've added using Microsoft.SPOT, still nothing. Time to check the documentation. Documentation states it's part of .NET Micro 4.0 and 4.1. So where is it? It looks like an error in the documentation; unless I'm doing something wrong it's not there in 4.1.


Some classes removed from the .NET Framework for the .NET Micro Framework have been replaced in Microsoft.SPOT.Hardware.Utility. And here we find SetLocalTime. But there's no SetTimeZone class in this namespace.


I set up a quick test to see if I could get ExtendedTimers to work. The promise here is that I can change the time zone at will and the ExtendedTimer will see the change and can be made to update displays etc. accordingly. Their documentation says they can respond to an enumerated set of events. I have this working on my current 'clock' where TimeEvents.Minutes is used to update the clock display.

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;


namespace ExtendedTimerEvents
{
    public class Program
    {
        public static void Main()
        {
            ExtendedTimer setTimer = new ExtendedTimer(new TimerCallback(set), null, ExtendedTimer.TimeEvents.SetTime);
            ExtendedTimer timer = new ExtendedTimer(new TimerCallback(junk), null, ExtendedTimer.TimeEvents.Second);
            Thread.Sleep(5000);
            Utility.SetLocalTime(new DateTime(2012, 1, 1));
            Thread.Sleep(Timeout.Infinite);
        }


        public static void junk(object state)
        {
            Debug.Print("Event! " + DateTime.Now.ToString());
        }


        public static void set(object state)
        {
            Debug.Print("Set! " + DateTime.Now.ToString());
        }
    }
}

In my tests the ExtendedTimer.TimeEvents.Second/Minute/Hour/Day events worked, but the SetTime and TimeZone events didn't. (Maybe SystemTimeChangedEventHandler?) Jens mentions in his book (middle of page 64) "... as well as after changing the time (using the SetTime method) or changing the time zone." The key here is the SetTime method, which I've yet to find. GHI devices like my FEZ Panda II have an on-board real-time clock (RTC) which provides a RealTimeClock.SetTime method. But this is a separate timing device and setting the RTC has nothing to do with events triggered from the SystemTime on the controller. I guess there's also the possibility events can be hooked up to RTC timing increments.

I also tried to see if I could get the TimeServiceSettings.AutoDayLightSavings method to work for me, as mentioned in my previous post. However, as the purpose of the TimeServiceSettings class is to manage time synchronisation with an NTP server, I can't see how it would work in this instance.

The TimeZoneId enumeration seems to have been discontinued after version 2.5 of the Micro Framework. So that's a dead end.

System.TimeZone.CurrentTimeZone is another .NET Framework component that's been removed for .NET Micro Framework.

There's also the TimeZoneInformation class. I built a test program (below) which sets up a TimeZoneInformation object. But do you think I can find how I make that the 'current' time zone? I feel this is one step from being a solid solution.


using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Time;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.FEZ;


namespace ExtendedTimerEvents
{
    public class Program
    {
        public static void Main()
        {
            DateTime today = new DateTime(2012, 1, 11);
            SystemTime dst = new SystemTime();
            SystemTime st = new SystemTime();


            // See notes on: http://msdn.microsoft.com/en-us/library/ee436345.aspx
            // http://australia.gov.au/about-australia/our-country/time
            dst.Year = (short)today.Year;
            dst.Hour = 2;
            dst.Month = 10;
            dst.DayOfWeek = 0;
            dst.Day = 1;


            st.Year = (short)today.Year;
            st.Hour = 2;
            st.Month = 4;
            st.DayOfWeek = 0;
            st.Day = 1;


            TimeZoneInformation info = new TimeZoneInformation();
            info.StandardBias = 60 * 10;
            info.StandardDate = st;
            info.StandardName = "AEST";
            info.DaylightBias = 60 * 11;
            info.DaylightDate = dst;
            info.DaylightName = "AEDST";


            TimeService.SetUtcTime(today.Ticks);
            Debug.Print("Local: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm"));
            Debug.Print("UTC  : " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm"));
            Debug.Print("Offset:" + info.Bias.ToString());
            Debug.Print("DSToff:" + info.DaylightBias.ToString());
            Debug.Print(" SToff:" + info.StandardBias.ToString());
        }
    }
}


Now I don't believe for a moment this is a well considered and comprehensive attempt to understand time zones and daylight savings in .NET Micro Framework. It's a shotgun approach. But I've written it down so, hopefully, when some new bit of information emerges, I can fit it into the patchwork of bits I know and make any use of it that's possible.

To sum it all up, it looks like for version 4.1 Microsoft has thrown all its eggs into the Microsoft.SPOT.Time basket. That's nice if you have an Internet connection and want to use an NTP server. If you want to manage time separately like I do, say with a GPS time source, you're on your own. So that's what I'm going to do. My own thang.

That is all.

Comments