Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inconsistent behavior of toLocaleString() in different browser

I am working on a project where I have to deal a lot with Date and Time. Server side technology is ASP.Net and at client side I am using jQuery and jQuery Week Calendar(a jQuery plugin).

So here is the problem described, I am receiving Data Time from server something like this 2012-11-13T04:45:00.00 in GMT format.

Now at client side, I want this Date Time to be converted to Locale Date Time Format, like whatever is could be IST, EST, PKT, etc.

To achieve this, I am using JavaScript method toLocaleString(). This only works fine in Chrome, in other browser it works inconsistently.

Here are its outputs in different browsers:

Google Chrome(Works fine):

Call:

new Date ("2012-11-13T04:45:00.00").toLocaleString();

Output:

Tue Nov 13 2012 10:15:00 GMT+0530 (India Standard Time)

Mozilla Firefox:

Call:

new Date ("2012-11-13T04:45:00.00").toLocaleString();

Output:

Tuesday, November 13, 2012 4:45:00 AM

Safari:

Call:

new Date ("2012-11-13T04:45:00.00").toLocaleString();

Output:

Invalid Date

Internet Explorer:

Call:

new Date ("2012-11-13T04:45:00.00").toLocaleString();

Output:

Tuesday, November 13, 2012 4:45:00 AM

For now these are the browsers where I tested.

Here is the Question:

I need a way to convert Data Time(having format like this 2012-11-13T04:45:00.00) To Locale Date and Time, no matter which browser client is using.

like image 301
Ishan Dhingra Avatar asked Nov 17 '12 07:11

Ishan Dhingra


2 Answers

The short answer is no. toLocaleString can be implemented however the developers wish. What your question implies is that Chrome outputs the string you want.

If you would like to output that format consistently you'll need to use a separate library - like DateJS.

To do this with DateJS will need some standard format specifiers available in core.js and some that are only available in extras.js. The documentation has a list of all the format specifiers.

The string you want is:

Tue Nov 13 2012 10:15:00 GMT+0530 (India Standard Time)

So to get this from DateJS you'll need:

"D M d Y H:i:s \G\M\TO (e)"

The syntax for DateJS is:

new Date ("2012-11-13T04:45:00.00").format("D M d Y H:i:s \G\M\TO (e)");
like image 160
funwhilelost Avatar answered Sep 28 '22 04:09

funwhilelost


Instead of using toLocaleString() which is outdated and implemented incorrectly for all web browsers, I strongly suggest using Globalize for date & time formatting.

Then to format date on the client side, all you have to do is to assign valid culture and simply call the format function:

Globalize.culture(theCulture);
Globalize.format( new Date(2012, 1, 20), 'd' ); // short date format
Globalize.format( new Date(2012, 1, 20), 'D' ); // long date format

Pretty simple, isn't it? Well, you'll have to also integrate it with your ASP.Net application, which complicates things a bit. First, you will need to reference the globalize.js the regular way:

<script type="text/javascript" src="path_to/globalize.js"></script>

Then it is best to include the right culture definition, that is the one you will need to use when formatting:

<script type="text/javscript" src="path_to/cultures/globalize.culture.<% = CultureInfo.CurrentCulture.ToString() %>.js"></script>

Finally you will need to set theCulture variable before you use it:

<script type="text/javscript">
    var theCulture = <% = CultureInfo.CurrentCulture.ToString() %>
</script>

Of course the more elegant way to do it, would be to create a property or the method in the code-behind that will write down the appropriate scripts for you and then reference just the method, say:

public string IntegrateGlobalize(string pathToLibrary)
{
  var sb = new StringBuilder();
  sb.Append("<script type=\"text/javascript\" src=\"");
  sb.Append(pathToLibrary);
  sb.AppendLine("/globalize.js\"></script>");
  sb.Append("<script type=\"text/javascript\" src=\"");
  sb.Append(pathToLibrary);
  sb.AppendLine("/cultures/globalize.culture.");
  sb.Append(CultureInfo.CurrentCulture);
  sb.AppendLine(\"></script>");
  sb.Append("<script type=\"text/javascript\">");
  sb.Append("var theCulture = ");
  sb.Append(CultureInfo.CurrentCulture);
  sb.AppendLine(";</script>");

  return sb.ToString();
}

Then all you have to do, is to reference this method in the (master?) page head:

<head>
  <% = IntegrateGlobalize("path_to_globalize") %>
  ...
</head>

Some issues

If you want to do it 100% correctly, you will need to enhance the Globalize culture generator to include 'g' format switch and then use this exact switch on the client side to format date:

Globalize.format( new Date(2012, 1, 20), 'g' ); // default date format

Why is that? Because 'g' is a default date format. This is what you'll get when you simply call DateTime's ToString() method without parameters (which will imply CultureInfo.CurrentCulture as the only parameter...). The default format is best, it will be either short or long, or any other, but the most commonly used by people using this culture.

I said that toLocaleString() is wrong for all web browsers. Why is that? That's because it will use web browsers settings and not the server-side detected culture. That means, that you might have mixed cultures in the same web page. That may happen if some of your dates are formatted on the server side and some other on the client side. That's why we needed to pass (detected) culture from the server side.
BTW. If you decide to include the regional preferences dialog to your web application, the mismatch would be even more visible, as toLocaleString() won't follow user settings...

like image 35
Paweł Dyda Avatar answered Sep 28 '22 03:09

Paweł Dyda