toLocaleString()在不同浏览器中的行为不一致

我正在开展一个项目,我必须处理很多日期和时间。 服务器端技术是ASP.Net,在客户端我使用的是jQuery和jQuery Week Calendar(一个jQuery插件)。

所以这里描述的问题是,我从服务器接收数据时间类似于2012-11-13T04:45:00.00 GMT格式。

现在在客户端,我希望将此日期时间转换为区域设置日期时间格式,就像IST,EST,PKT等一样。

为实现这一点,我使用JavaScript方法toLocaleString() 。 这仅适用于Chrome,在其他浏览器中工作不一致。

以下是不同浏览器的输出:

谷歌浏览器(工作正常):

呼叫:

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

输出:

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

火狐浏览器:

呼叫:

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

输出:

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

苹果浏览器:

呼叫:

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

输出:

 Invalid Date 

IE浏览器:

呼叫:

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

输出:

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

现在这些是我测试过的浏览器。

这是问题

我需要一种方法将数据时间(格式如此2012-11-13T04:45:00.00 )转换为语言环境日期和时间,无论使用哪个浏览器客户端。

最简洁的答案是不。 然而,开发人员希望实现toLocaleString。 您的问题意味着Chrome会输出您想要的字符串

如果您想要一致地输出该格式,则需要使用单独的库 – 如DateJS 。

要使用DateJS执行此操作,将需要core.js中提供的一些标准格式说明符,以及仅在extras.js中可用的一些标准格式说明符。 该文档包含所有格式说明符的列表。

你想要的字符串是:

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

所以要从DateJS获得这个,你需要:

 "DM d YH:i:s \G\M\TO (e)" 

DateJS的语法是:

 new Date ("2012-11-13T04:45:00.00").format("DM d YH:i:s \G\M\TO (e)"); 

我强烈建议使用Globalize进行日期和时间格式化,而不是使用过时且不能为所有Web浏览器实现的toLocaleString()

然后要在客户端格式化日期,您所要做的就是分配有效的文化并简单地调用格式函数:

 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 

很简单,不是吗? 好吧,你还必须将它与你的ASP.Net应用程序集成,这会使事情变得复杂。 首先,您需要以常规方式引用globalize.js:

  

然后最好包括正确的文化定义,即格式化时需要使用的定义:

  

最后,您需要在使用之前设置theCulture变量:

  

当然,更优雅的方法是在代码隐藏中创建属性或方法,为您写下适当的脚本,然后引用方法,比如:

 public string IntegrateGlobalize(string pathToLibrary) { var sb = new StringBuilder(); sb.Append(""); sb.Append(""); sb.Append(""); return sb.ToString(); } 

那么你要做的就是在(master?)页面头中引用这个方法:

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

一些问题

如果你想100%正确地完成它,你需要增强Globalize文化生成器以包含'g'格式开关,然后在客户端使用这个确切的开关来格式化日期:

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

这是为什么? 因为’g’是默认的日期格式。 这就是你在没有参数的情况下调用DateTimeToString()方法时会得到的结果(这意味着CultureInfo.CurrentCulture是唯一的参数……)。 默认格式最好,它可以是短或长,或任何其他,但最常用于使用此文化的人。

我说toLocaleString()对所有Web浏览器都是错误的。 这是为什么? 那是因为它将使用Web浏览器设置而不是服务器端检测到的文化。 这意味着,您可能在同一网页中混合了文化。 如果您的某些日期在服务器端格式化,而另一些日期在客户端格式化,则可能会发生这种情况。 这就是我们需要从服务器端传递(检测到)文化的原因。
BTW。 如果您决定将区域首选项对话框包含在Web应用程序中,则不匹配将更加明显,因为toLocaleString()将不会遵循用户设置…

要将时间转换为服务器上特定于语言环境的字符串,可以使用DateTime.ToLongDateString方法。 在该页面上,请参阅有关DateTimeFormatInfo类的“当前文化对象”(在服务器上)的说明。 确保设置正确。

任何答案都没有解决这个问题的根本原因。 OP说:

我收到服务器的数据时间,格林威治标准时间为2012-11-13T04:45:00.00

GMT不是一种格式。 此字符串采用ISO 8601扩展格式,未指定任何时区。 ISO 8601规范规定,如果没有限定符,则表示当地时间 。 要指定GMT,您可以在末尾附加Z ,或者可以附加偏移量,例如+00:00

问题是,ECMAScript(v1 – v5.1)在规范中没有遵守这一规定。 它实际上说应该被解释为UTC而不是本地时间。 一些浏览器尊重ISO规范,有些浏览器尊重ECMA规范。 这已针对版本6进行了更正,并且大多数浏览器都已遵守。

所以 – 如果你打算传输基于UTC / GMT的时间戳,那么在服务器端,你应该总是发送一个Z所以没有歧义。

尽管如此,即使正确解释了该 ,也无法保证字符串在浏览器中的格式相同。 为此,你确实需要一个库。 我推荐moment.js ,但还有其他人。