Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display localized date and time information to web users with ASP.NET

I have an ASP.NET application and a UTC time stamp on the server. I want to display the time stamp to the user in the right time zone and using local date/time format.

E.g. Jan 2, 2012 14:00:00 UTC should show as 1/2/2012 9:00 AM to a user in New York, United States (UTC -0500) and as 02/01/2012 14:00 to a user in London, UK.

This seemingly simple task proved to be surprisingly difficult. MSDN has an article with the same title, but it talks about parsing user input rather than displaying server-side data, so it does not fully apply.

Time zone offset is easily determined on the client via JavaScript

offset = new Date().getTimezoneOffset();,

but JavaScript provides very poor support for date/time formatting. All you get is toLocaleString() method, which results in ugly long string such as Monday, January 02, 2012 9:00:00 AM. There is no provision for shorter formats, so on the client we're stuck with good time zone info and bad date/time format capabilities.

The situation is exactly opposite on the server. We can leverage Accept-Language HTTP header to get the user locale (not the best choice, but may be good enough), and then tap into the .NET database of known locales, so our code goes along the lines of

CultureInfo userCulture = new CultureInfo(Request.UserLanguages[0]); plus some error handling.

But then we are stuck on the time zone problem. Yes, one can get it via JavaScript and then pass back as a cookie or as postback data, but what if we need to display dates on the very first page of the application? One may argue that the first page is always the login page, but it is not so when user login info is persisted between sessions ("remember me" option). The solution to that could be to save time zone offset as part of user profile, but then it may easily become stale (getting on and off daylight savings time between sessions).

Is there a comprehensive solution to this problem that performs well and does not require writing tons of code? I am very curious, please advise.

like image 331
Ivan Krivyakov Avatar asked Jan 03 '12 05:01

Ivan Krivyakov


1 Answers

You should pass the time string to the client in a standard form, such as ISO8601:

var timeString = '2012-01-02T16:00:00Z';

Some browsers will correctly parse ISO8601 strings and some wont, so parse it manually to be sure. That is pretty simple—create a local date object then set the UTC date and time:

function localDateFromUTC(s) {

  var x = s.split(/[-\s:tz]/i);
  var d = new Date();

  d.setUTCFullYear(x[0], x[1], x[2]);
  d.setUTCHours(x[3], x[4], x[5]);
  return d;
}

var s = '2012-01-02T16:00:00Z';
var d = localDateFromUTC(s);
alert(d); // Shows local date and time for the provided UTC date and time

If you want a specific output, you need to format it manually, e.g.

function formatDate(d) {
  var days = ['Sunday','Monday','Tuesday','Wednesday',
              'Thursday','Friday','Saturday'];
  var months = ['January','February','March','April','May','June','July',
                'August','September','October','November','December'];

  return days[d.getDay()] + ', ' + d.getDate() + ' ' + 
              months[d.getMonth()] + ', ' + d.getFullYear();
} 

You can try using toLocaleString() but results vary greatly across browsers, most seem to ignore local settings anyway.

like image 123
RobG Avatar answered Sep 18 '22 23:09

RobG