KnockoutJS Value Converter to Deal with JSON Dates
A few weeks ago, Scott Hanselman blogged about the challenges with working with JSON dates and the ASP.NET Web API. In the post he described how the current version of the Web API sends back dates in Epoch time. The conclusion of his post was that JSON.NET, which the Web API will use OOTB, will use ISO 8601 for JSON dates moving forward.
This is all an ideal solution if you're using the latest version of the ASP.NET Web API that uses JSON.NET. However, what if you're in a situation where you are a client developer and you are not in control of the server? That is, you have to deal with an Epoch date in your JavaScript code. In this case, you might be working on a device such as an iPad that wants dates in a certain format (e.g., yyyy-mm-dd) and this certainly is not compatible with Epoch. Hanselman did show a KnockoutJS binding handler in his post but you want this to seamless be a 2-way operation. That is, when you get the epoch date from the server, you want it displayed in your format – then when you're done editing it, you want it sent back to the server in epoch format.
A quick and easy way to do this with KnockoutJS is to use a "value converter" – this is just a specific type of computed observable that includes both a read and write function. In the jsFiddle below, the "read" function takes an epoch date and converts it to the yyyy-mm-dd format. I can edit the formatted date however I want and the "write" function will automatically be invoked to convert my formatted date back to epoch time. This completes to 2-way data binding:
This code does not take into account daylight savings time (there is also some manual string parsing for the dates) – however, there are other JS libraries you can incorporate into the code above that does take daylight savings time elegantly into account. As you can see, KnockoutJS provides some convenient features to transform between two different formats without having to litter your code with conditional logic all over the place.