The Netduino forums have been replaced by new forums at community.wildernesslabs.co.
This site has been preserved for archival purposes only
and the ability to make new accounts or posts has been turned off.
Still learning, internet way to grab date and time on startup
using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
namespace SNTP
{
public class Program
{
public static void Main()
{
Microsoft.SPOT.ExtendedTimeZone.SetTimeZone(TimeZoneId.Berlin);
Microsoft.SPOT.Hardware.Utility.SetLocalTime(GetNetworkTime());
}
public static DateTime GetNetworkTime()
{
return null;
}
}
}
Hi Everyone
Totally disregard my last post. The NETMF documentation is in error as
Microsoft.SPOT.ExtendedTimeZone.SetTimeZone() was dropped after version 3.0
in favor of an intrinsic time service in framework. I.E. SNTP is built into
the framework.
What does this mean?
Basically if you have a network interface the netduino can query a government time server for the current time and if you elect periodically re-sync to correct for drift. If you do not have connectivity to the internet, you can substitute a windows domain controller as your time source.
So if you have network connectivity you do not need a real time clock in your solution!
I will post an example later. If you want to dive in checkout Microsoft.SPOT.Time.TimeService.UpdateNow().
Cheers!
freds,
Quick note: due to the size of it, I don't believe we build the time service feature into the Netduino firmware. You could probably compile it in though...
[All that said, if the time service is written in C# code...then you can include it in your project.]
Chris
This is for standard NETMF sockets. IT should be ok with the Plus, but I have not tested it yet.
My goal is to have DateTime.Now return the correct local date/time. I also wrote code based on the same blog post and it retrieves the UTC time fine on my NetduinoPlus, but since the SetTimeZone method was dropped and the SPOT.Time Libraries are not included, that leaves no way of setting the timezone in the device, as far as I can tell. So despite having some remnants of TimeZone enumerations and a TimeZoneInformation object, there appears to be no way to do this. I think what I will have to do is create my own TimeZone collection then apply it when I set the local time. But then, although DateTime.Now will return the correct local time, DateTime.UtcNow would return the wrong time because the TimeZone is not set. Ugh. I don't mind leaving out the SPOT.Time, but there needs to be a way to set the TimeZone... So in addition to the Microsoft.SPOT.Hardware.Utility.SetLocalTime method, there should be a Utility.SetTimeZone since these are not available: Microsoft.SPOT.ExtendedTimeZone.SetTimeZone(TimeZoneId.Eastern); Microsoft.SPOT.Time.TimeService.SetTimeZoneOffset(-300);
P.S. Also, I know this is a departure from standard .NET, but I think DateTime.Now should be a nullable type and it should be null at startup until it is populated... It is crazy to initialize System DateTime to 1/1/1900. That will never be the correct date. Ever!
I've made a modification to to Chris's code so that you can compensate for timezones. It's just an extra argument that is the time difference between UTC and the timezone you want to set the Netduino to.
public static DateTime NTPTime(String TimeServer, int UTC_offset)
{
// Find endpoint for timeserver
IPEndPoint 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;
TimeSpan offsetAmount = new TimeSpan(0, UTC_offset, 0, 0, 0);
DateTime networkDateTime = (dateTime + offsetAmount);
return networkDateTime;
}
So if you were in the Eastern time zone of the United States, you just call:
That looks like a good way of doing it. I wanted to post here as well, the solution I am using, which is a combination of what others have done. It's not totally cleaned up, but it's been working great for me for a few months to the point where I have totally forgotten about it. It is implemented as an extension method and the usage looks like this:
Note, you should specify the timezone if you want it to use local time. Otherwise, you'll get UTC for everything. In the example above, I am setting my Netduino Date/Time to EST, which is UTC-5 hours.
This Extension.cs file has no namespace specified, so you can drop it into any project and the methods will magically be there! Also, no need to add using statements in each file this way...
This is unrelated, but for the sake of search hits; some other methods in the file are:
Valkyrie-MT's method worked great for me but did not take into account Daylight Savings.
-8 (PST) shows up as an hour off for half of the year
I'm digging through the code now but haven't seen anything yet...
Valkyrie-MT's method worked great for me but did not take into account Daylight Savings.
-8 (PST) shows up as an hour off for half of the year
Check out the Daytime Protocol (RFC-867) that operates on port 13 on various servers such as "time-nw.nist.gov".
RFC-867 doesn't specify a format, but the format of the returned time code from NIST servers is this: JJJJJ YR-MO-DA HH:MM:SS TT L H msADV UTC(NIST) OTM
See the following for a list of servers. Try and choose one that is close by and "recommended for new users." Heed the warning about not querying the server more often than once every four seconds. http://tf.nist.gov/tf-cgi/servers.cgi
Valkyrie-MT's method worked great for me but did not take into account Daylight Savings.
-8 (PST) shows up as an hour off for half of the year
I'm digging through the code now but haven't seen anything yet...
I think every method I have seen will have this problem because the timezone support is not in the netduino. The methods I have been using simply get the date/time from a time server on the web and only applies a time offset, notice though that it is not a time zone. TomYee is right, in that the TT field is the key here. We'd have to create a singleton class that is instantiated when a time request is made and continues running in the background to check once a month if this is the month for the time change. Then use the value from TT to determine what day the time change will happen. Then on that day, poll every every hour for a time change... The continuously running singleton would poll the time servers every month, then every hour on the day of the timezone change. It's totally do-able, but a bit abusive to the NIST servers...
Update - First off, we may have better time support in the next version of .NET MF:
COMMITTED: Time Protocol (SNTP) for lwIP, please note we might look into integrating RFC4833 for supporting time zone as well
Also, there is some good time parsing code here that could be used to fill in the Time Zone stuff. I'll probably wait and see what we get with .NET MF 4.2.
so it does appear that Valkyrie-MT is right. there is no way to set the system time.
i cant believe that. anyone care to expound on why its not there?
is it some byproduct of the way the CLR is implemented and that there is no underlying OS to call (like with a win32 invoke)?
also, anyone got time to offer a short (50 words or less) explanation for this newb on why you would build a timer with a 555 chip?
.cheers.
i overlooked it, but in the first post on this thread he calls the method:
Microsoft.SPOT.Hardware.Utility.SetLocalTime();
so you can set it. it just doesnt persist between bootups.
This is my first post here
Got the netduino plus device today.
To init the DateTime.Now value of de the device, the assembly build Version can be of some use.
First, edit the AssemblyInfo.cs file (properties):
When de device is reset, the original datetime of the build is used as a starting value.
It is not NTP but maybe this can be usefull for debugging etc.
I just upgraded to the 4.2 RC1 firmware for the netduino plus, and now this function doesnt seem to work for me. It gets to the
s.Connect(ep);
and just hangs there. I thought it might have something to do with the network, but i can ping the device from my computer and get responses from it's webserver. Does anyone have any idea why this would change when moving to the 4.2 firmware?
I just upgraded to the 4.2 RC1 firmware for the netduino plus, and now this function doesnt seem to work for me. It gets to the
s.Connect(ep);
and just hangs there. I thought it might have something to do with the network, but i can ping the device from my computer and get responses from it's webserver. Does anyone have any idea why this would change when moving to the 4.2 firmware?
Uh oh... I'm seeing the same thing. The Socket.Connect method is broken in 4.2 RC1 (at least for UDP). It does not seem to hang with the Socket.SendTo method, although I haven't looked yet to see if that method works. We need to characterize what works and what doesn't and get it to the .NET MF team soon.
Update: The Socket.SendTo Method does work, so we could work around this, but now I'm concerned about the TCP socket stuff... That needs to be tested now.
Update2: The following workaround, works... comment out the connect line and change s.Send(ntpData) to s.SendTo(ntpData, ep):
This morning we changed to Daylight Saving Time in EU.
Rather than using DateTime.Now to display date and time, I use DST which comes from this function:
public static DateTime DST
{
get
{
DateTime dt = DateTime.Now;
if (dt.Month < 3 || dt.Month > 10) return DateTime.Now;
if (dt.Month > 3 && dt.Month < 10) return DateTime.Now.AddHours(1);
if (dt.Month == 3)
{ // in march
if ((dt.Day - (int)dt.DayOfWeek) < 25) return DateTime.Now;
if (((int)dt.DayOfWeek == 0) && (dt.Hour < 2)) return DateTime.Now;
return DateTime.Now.AddHours(1);
} // in october
if ((dt.Day - (int)dt.DayOfWeek) < 25) return DateTime.Now.AddHours(1);
if (((int)dt.DayOfWeek == 0) && (dt.Hour < 2)) return DateTime.Now.AddHours(1);
return DateTime.Now;
}
}
When de device is reset, the original datetime of the build is used as a starting value.
It is not NTP but maybe this can be usefull for debugging etc.
Alphons, Thanks. I'm using this code to initialize my Netduino Go (which has no internet...yet). It's a great trick in that it set's the time almost perfectly during the development phase of edit, build, edit, build.
Can you explain to me why the AssemblyInfo.cs file edit was necessary? What does that change do?