At teamaton we're currently developing our own Time Tracking tool that we'll be using instead of KeepTempo as soon as it's good enough. We even plan on making it accessible to the public later but that's a different story.
We chose Angular.js to develop the frontend and now want to synchronize our time tracking records with our ASP.NET WebAPI backend. One property of such a record is the date and time it was created at, createdUtc. Let's look at how we can send those date-time values to the server and back again.
Some Background on Date and DateTime
JavaScript Date instances are seeded at 01/01/1970 00:00:00 and can be instantiated by passing to the Date() constructor the number of milliseconds that have passed since that moment in time. Date.now() will directly output this number, at the moment of writing these words it returned the value 1 411 240 284 042. This value is what all other representations of a given Date instance will be based on.
In .NET we have the DateTime type and its seed value is 01/01/0001 00:00:00. Internally, DateTime instances count time in Ticks, where one tick equals 100 nanoseconds, i.e. 0.000 000 1 seconds, thus delivering a theoretical precision of 10000 times that of the JavaScript equivalent. When writing these words, the current number of Ticks of DateTime.Now was 635 468 449 058 588 764 (I use LINQPad to execute C# code snippets).
How to Convert JavaScript Date to .NET DateTime
So how do we convert those values into each other?
If we decide to send the number of milliseconds in a given JavaScript Date instance to our .NET server we can reconstruct an equivalent DateTime instance by seeding it with 01/01/1970 and just adding the milliseconds we got from the client to it:
- Record.CreatedUtc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(milliseconds);
Going the other way, we actually need to get hold of a TimeSpan instance which has the property TotalMilliseconds that gives us what we want. We'll do that by substracting a DateTime instance representing the 01/01/1970 from the DateTime instance we want to send to the client:
- (Record.CreatedUtc - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds
The code looks a bit ugly because we take care to work with UTC dates so that our code will run the same for clients and servers around the world. It's a very good idea to work with UTC dates internally and only convert them to local dates when you want to display them somewhere.
… or Just Use Date Strings
There's another way to transfer date objects between JavaScript and your server: using a standardized string representation that both sides will be able to generate and parse.
In JavaScript you would use Date.toISOString() and in .NET DateTime.ToString("O") (see the MSDN for the O format string).
Happy coding!