Main Site Documentation

Accurate DST time


#1

Found an interesting formula for calculating Daylight Saving Time and thought I would share some code for those less experienced than myself. Hope it helps someone.

public class Program
    {
    private static bool timeUpdate = false;

        public static void Main()
        {
            
            Microsoft.SPOT.Net.NetworkInformation.NetworkInterface NI = Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0];

            if (NI.IsDhcpEnabled == false)
            {
                Debug.Print("Static: \nIP Address = " + NI.IPAddress + " \nNet Mask = " + NI.SubnetMask + " \nGateway = " + NI.GatewayAddress);
            }

            while (true)
            {
                if (timeUpdate == false)
                {
                    //myTime Update = new myTime();
                    //Update.NTPTime("time-a.nist.gov", -300);
                    setTime updateTime = new setTime();     // instantiate an instance of setTime class
                    Utility.SetLocalTime(updateTime.NTPTime("time-a.nist.gov"));    //update time using setTime's NTPTime method
                    timeUpdate = true;
                    Debug.Print("Updated Time: " + DateTime.Now.ToString()); //displays updated time in VS2010 output window
                }                
            }
        }
    }

    public class setTime
    {
        DateTime networkDateTime;

        public DateTime NTPTime(String TimeServer)
        {            
            try
            {
                // Find endpoint for timeserver
                EndPoint ep = new IPEndPoint(Dns.GetHostEntry(TimeServer).AddressList[0], 123);

                // Connect to timeserver
                Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                s.Connect(ep);
                // Make send/receive buffer
                byte[] ntpData = new byte[48];
                Array.Clear(ntpData, 0, 48);
                // Set protocol version
                ntpData[0] = 0x1B;
                // Send Request
                s.Send(ntpData);
                // Receive Time
                s.Receive(ntpData);
                byte offsetTransmitTime = 40;
                ulong intpart = 0;
                ulong fractpart = 0;
                for (int i = 0; i <= 3; i++)
                    intpart = (intpart << 8) | ntpData[offsetTransmitTime + i];
                for (int i = 4; i <= 7; i++)
                    fractpart = (fractpart << 8) | ntpData[offsetTransmitTime + i];
                ulong milliseconds = (intpart * 1000 + (fractpart * 1000) / 0x100000000L);
                s.Close();

                TimeSpan timeSpan = TimeSpan.FromTicks((long)milliseconds * TimeSpan.TicksPerMillisecond);
                DateTime dateTime = new DateTime(1900, 1, 1);
                dateTime += timeSpan;
                int offset = getOffSet(dateTime);   //sets UTC time
                TimeService.SetTimeZoneOffset(offset);
                TimeSpan offsetAmount = TimeZone.CurrentTimeZone.GetUtcOffset(dateTime);
                networkDateTime = (dateTime + offsetAmount);

                return networkDateTime;
            }
            catch
            { 
                Debug.Print("Time update failed...");
                return networkDateTime;                
            }
        }
    
        private int getOffSet(DateTime NTPServerTime)
        {
            //This method returns a UTC offset(in minutes) by calculating the correct day DST occurs and adjusting offset accordingly.
            //This version only works in timezones with a negative initial offset(a.k.a North America .et al) Calculations are accurate to year 2099.

            int offSetInMinutes = -300; // set for US central time(in minutes). Set for your timezone.
            int year = NTPServerTime.Year;
            double marchDay = 14 - (System.Math.Floor(1 + year * 5 / 4) % 7);   //find day in March the DST occurs
            int intMarchDay = (int)marchDay;    //cast marchDay to int
            double novDay = 7 - (System.Math.Floor(1 + year * 5 / 4) % 7);      //find day in November the DST occurs
            int intNovDay = (int)novDay;    //cast novDay to int
            Debug.Print("marchDay: " + intMarchDay.ToString());
            Debug.Print("novDay: " + intNovDay.ToString());
            DateTime marchChange = new DateTime(year, 3, intMarchDay, 2, 0, 0);
            DateTime novChange = new DateTime(year, 11, intNovDay, 2, 0, 0);

            if (NTPServerTime <= marchChange || NTPServerTime >= novChange)
            {
                offSetInMinutes -= 60; //Subtract and hour for DST change
                //Debug.Print("OffSet: " + offSetInMinutes.ToString());
            }
            else
            {
                offSetInMinutes += 0;
            }
            
            return offSetInMinutes;
        }

    }

#2

Hello !

Thank you for sharing :smiley:

This seems to be for the US only. But you still have to program in hard your gmtoffset, I.E. you must know in which timezone you are. Outside the US, you may try to use a very interresting piece of code here : http://code.tinyclr.com/project/274/timezone-management-via-xml/ that is addressing the problem for worldwide. But you still need to now where you are :wink: