Hi Guys,
I did my homework. Daylight savings is (indeed) not implemented in NETMF. Here is what I found : The NTP servers give only one time : the universal time at GMT. There is no notion of TimeZone nor Daylight Savings. You have to implement it in your code.
Implementing TimeZone is easy. One variable containing the number of minutes to add to GMT, and that’s it.
For Daylight Savings, it’s a little bit trickier, because it depends on the country you leave in (that’s why you are been asked about a town or a country when you install an operating system)
So I implemented a short class that synchronize the COBRA clock with NTP servers, applying TimeZone and Daylight savings for European Countries. Outside Europe, you may need to modify the code to apply the daylight savings according to your country.
Using the class is VERY simple, you just need to instanciate an object of the class and that’s it. I used event handlers, so each time the synchronisation with NTP servers is done, there is a check for Daylight savings, so , you automatically switch between summer and winter time.
I need to add a piece of code to save the current date and time in static memory, in case there is a reboot and the Cobra cannot reconnect to Internet.
Here is the class, followed by and example of how to use it :
using System;
using System.Net;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Time;
class NTPService
{
private static int localTimeZone = 60; // Time shift for Paris - Change according to your location
private static int daylightSavingsShift = 0; // Should be 60 in summer time, 0 during winter
private string primaryNTPServer = "fr.pool.ntp.org"; // Primary NTP server, put the nearest from your location
private string secondaryNTPServer = "pool.ntp.org"; // Alternate NTP server, choose the most generic one
private TimeServiceSettings NTPTime; // NTP Client configuration
public NTPService() // Initialize and start the NTP synchronization
{
// Initialize the NTP parameters
NTPTime = new TimeServiceSettings(); // Initialize the configuration structure
NTPTime.AutoDayLightSavings = true; // That does nothing on NETMF, indeed
NTPTime.ForceSyncAtWakeUp = true; // Not sure that works
NTPTime.RefreshTime = 7200; // Refresh rate un second, here 2 hours (7200), put 60 for testing purpose
// Get the IP addresses from the NTP servers using DNS requests
try
{
NTPTime.PrimaryServer = Dns.GetHostEntry(primaryNTPServer).AddressList[0].GetAddressBytes();
NTPTime.AlternateServer = Dns.GetHostEntry(secondaryNTPServer).AddressList[0].GetAddressBytes();
}
catch (Exception e)
{
Debug.Print("NTPService : Exception on DNS lookup for NTP servers address");
Debug.Print(e.Message);
}
// Assign the Event handlers to manage the updates and starts the service
TimeService.Settings = NTPTime;
TimeService.SystemTimeChanged += new SystemTimeChangedEventHandler(onSystemTimeChanged);
TimeService.TimeSyncFailed += new TimeSyncFailedEventHandler(onTimeSyncFailed);
TimeService.Start();
}
static void onSystemTimeChanged(Object sender, SystemTimeChangedEventArgs e) // Called on successful NTP Synchronisation
{
DateTime now = DateTime.Now; // Used to manipulate dates and time
#region Check is we are in summer time and thus daylight savings apply
// Check if we are in Daylight savings. The following algorythm works pour Europe and associated countries
// In Europe, daylight savings (+60 min) starts the last sunday of march and ends the last sunday of october
DateTime aprilFirst = new DateTime(now.Year, 4, 1);
DateTime novemberFirst = new DateTime(now.Year, 11, 1);
int[] sundayshift = new int[] { 0, -1, -2, -3, -4, -5, -6 };
int marchLastSunday = aprilFirst.DayOfYear + sundayshift[(int)aprilFirst.DayOfWeek];
int octoberLastSunday = novemberFirst.DayOfYear + sundayshift[(int)novemberFirst.DayOfWeek];
if ((now.DayOfYear >= marchLastSunday) && (now.DayOfYear < octoberLastSunday))
daylightSavingsShift = 60;
else
daylightSavingsShift = 0;
TimeService.SetTimeZoneOffset(localTimeZone + daylightSavingsShift);
#endregion
// Display the synchronized date on the Debug Console
now = DateTime.Now;
string date = now.ToString("dd/MM/yyyy");
string heure = now.ToString("HH:mm:ss");
Debug.Print(date + " // " + heure);
}
static void onTimeSyncFailed(Object sender, TimeSyncFailedEventArgs e) // Called on unsuccessful NTP Synchronisation
{
Debug.Print("NTPService : Error synchronizing system time with NTP server");
}
}
How to use the class :
namespace EMXTest
{
public class Program
{
public static void Main()
{
NTPService timeSynchro;
#region Get an IP address from the DHCP Server
Microsoft.SPOT.Net.NetworkInformation.NetworkInterface NI = Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0];
if (NI.IsDhcpEnabled == false)
{
Debug.Print("Enabling DHCP.");
NI.EnableDhcp();
Debug.Print("DCHP - IP Address = " + NI.IPAddress + " ... Net Mask = " + NI.SubnetMask + " ... Gateway = " + NI.GatewayAddress);
}
else
{
Debug.Print("Renewing DHCP lease.");
NI.RenewDhcpLease();
Debug.Print("DCHP - IP Address = " + NI.IPAddress + " ... Net Mask = " + NI.SubnetMask + " ... Gateway = " + NI.GatewayAddress);
}
#endregion
timeSynchro = new NTPService();
while (true)
{
Debug.Print("I'm Here");
Thread.Sleep(10000);
}
}
}
}
Enjoy.
Stephan.