One common problem with displaying local dates an times in a browser is that you get no information about the current time zone a browser is in. The browser will tell you the preferred language through the Accept-Language HTTP header but there is no such header for the users time zone. This means that it is easy enough to display a DateTime in the servers time zone but not in the users time zone. Now if your server is in the same time zone as your users this isn't much of an issue.. However that is quite often not the case, either because your web application is used in multiple geographical regions or because you are using Windows Azure as you hosting solution. In the case of Azure the server it set to run at UTC so quite unlikely to display the correct local time.
Storing the current offset in a cookie
One approach taken is to store the time zone offset in a cookie and use that as described here. While this technique works it has a few drawbacks.
For one the user will not have a timezoneoffset cookie the first time he visits your website. That can be fixed by setting the timezoneoffset cookie and reloading the page but that results in extra requests.
Another issue is that even when the timezoneoffset cookie is present we have no way of knowing if this is actually correct. After all we could just have switched to or from daylight saving time or taken a flight across an time zone border. Again something we can fix with a reload but with the same drawback.
But even if we know the timezoneoffset cookie is correct we can only do so much with it. It contains the current time zone offset information but no information about what the offset is for another date time. As different time zones have different dates for daylight saving time and different amounts of time adjusted we can not make any assumptions there. So we can correctly display the current date time in the local time zone but not that of any other date time value.
A better approach using Moment.js
Though not strictly required for this approach using moment.js is highly recommended as it makes the whole process a lot easier.
Instead of trying to format the DateTime on the server where we don't have enough information doing so in the browser is a far better place. Using this technique we always return the UTC DateTime to the browser. Once in the browser we can convert this UTC DateTime string to a Date object, and format that. The browser knows all about the current time zone so has no problems applying the correct time zone offset for us. Doing so with a plane JavaScript Date() object isn't hard but using moment.js makes this a lot easier.
That leaves us with sending the data to the browser, finding it there and displaying it in the correct format. It turns out that the HTML5 <time> element is perfect for this purpose. We add the machine parse able format in the standard datetime attribute and format we want to use in an custom date-format attribute. All that is left is a bit of jQuery script to select the time elements and do the conversion.
1: $(function () {
2:
3: $("time[data-format]").each(function () {
4:var el = $(this);
5:var dt = moment(el.attr("datetime"));
6: el.text(dt.format(el.data("format")));
7: });
8: })
The markup could be generated like this:
1: The current time in the browser is: <timedatetime="<%= DateTime.UtcNow.ToString("u") %>"data-format="hh:mm:ss A"></time>
Note that the time being rendered is always done using UTC.
A simple example running on Windows Azure can be found here.
Nice and simple right? Just the way I like it :-)
Enjoy!