Setting the Netduino's DateTime Automatically

Whenever the Netduino boots up or is restarted, you'll find that the date and time reverts to the default values.  Since the release of the Netduino Plus, ethernet access has been built in and provides a welcome solution to this issue.

The Network Time Protocol (NTP) provides an easy way to sync a device (such as your Windows computer) with a network time server.  By invoking an NTP server at start-up, the Netduino will automatically set its DateTime.

The following code was provided on a blog by Michael Schwarz and slightly modified to accept an additional (time zone) parameter:

using System;
using System.Net;
using System.Net.Sockets;

public static class Ntp
{
    public static bool UpdateTimeFromNtpServer(string server, int timeZoneOffset)
    {
        try
        {
            var currentTime = GetNtpTime(server, timeZoneOffset);
            Microsoft.SPOT.Hardware.Utility.SetLocalTime(currentTime);

            return true;
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    /// Get DateTime from NTP Server
    /// Based on:
    /// http://weblogs.asp.net/mschwarz/archive/2008/03/09/wrong-datetime-on-net-micro-framework-devices.aspx
    /// </summary>
    /// <param name="timeServer">Time Server (NTP) address</param>
    /// <param name="timeZoneOffset">Difference in hours from UTC</param>
    /// <returns>Local NTP Time</returns>
    private static DateTime GetNtpTime(String timeServer, int timeZoneOffset)
    {
        // Find endpoint for TimeServer
        var ep = new IPEndPoint(Dns.GetHostEntry(timeServer).AddressList[0], 123);

        // Make send/receive buffer
        var ntpData = new byte[48];

        // Connect to TimeServer
        using (var s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
        {
            // Set 10s send/receive timeout and connect
            s.SendTimeout = s.ReceiveTimeout = 10000; // 10,000 ms
            s.Connect(ep);

            // Set protocol version
            ntpData[0] = 0x1B;

            // Send Request
            s.Send(ntpData);

            // Receive Time
            s.Receive(ntpData);

            // Close the socket
            s.Close();
        }

        const byte offsetTransmitTime = 40;

        ulong intpart = 0;
        ulong fractpart = 0;

        for (var i = 0; i <= 3; i++)
            intpart = (intpart << 8) | ntpData[offsetTransmitTime + i];

        for (var i = 4; i <= 7; i++)
            fractpart = (fractpart << 8) | ntpData[offsetTransmitTime + i];

        ulong milliseconds = (intpart * 1000 + (fractpart * 1000) / 0x100000000L);

        var timeSpan = TimeSpan.FromTicks((long)milliseconds * TimeSpan.TicksPerMillisecond);
        var dateTime = new DateTime(1900, 1, 1);
        dateTime += timeSpan;

        var offsetAmount = new TimeSpan(timeZoneOffset, 0, 0);
        var networkDateTime = (dateTime + offsetAmount);

        return networkDateTime;
    }
}

Here's a short list of some NTP servers:

  • pool.ntp.org (actually it's a collection of servers behind a single address)
  • time.nist.gov
  • time-a.nist.gov
  • time-b.nist.gov
Pass one of these server names as a string and call during your project's Main() method:
private static bool SetTime()
{
    var result = Ntp.UpdateTimeFromNtpServer("time.nist.gov", -4);  // Eastern Daylight Time
    Debug.Print(result ? "Time successfully updated" : "Time not updated");

    return result;
}
It's unfortunate that the Netduino doesn't support Microsoft.SPOT.ExtendedTimeZone.SetTimeZone() to allow a time zone to be specified (thus eliminating the need for that extra "timeZoneOffset" parameter I added to two of the methods) or even the Microsoft.SPOT.Time.TimeService.UpdateNow() method, which would make all of the code above obsolete. However, it's understandable some libraries needed to be stripped due to memory size limitations. I'm still a huge fan of the Netduino; it still offers a lot of functionality on a very small and cheap device.

Additional References:

One thought on “Setting the Netduino's DateTime Automatically

Leave a Reply

Your email address will not be published. Required fields are marked *