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

Javascript ToLocalString()在不同浏览器中的行为不一致,javascript,jquery,datetime,multiple-browsers,Javascript,Jquery,Datetime,Multiple Browsers,我正在做一个项目,在这个项目中我必须处理很多日期和时间。服务器端技术是ASP.Net,在客户端我使用jQuery和jQuery周日历(一个jQuery插件) 下面是所描述的问题,我正在从服务器接收数据时间,类似于GMT格式的2012-11-13T04:45:00.00 现在在客户端,我想把这个日期时间转换成本地日期时间格式,比如IST、EST、PKT等等 为了实现这一点,我使用JavaScript方法toLocaleString()。这只适用于Chrome浏览器,而在其他浏览器中则不一致 以下是

我正在做一个项目,在这个项目中我必须处理很多日期和时间。服务器端技术是ASP.Net,在客户端我使用jQuery和jQuery周日历(一个jQuery插件)

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

现在在客户端,我想把这个日期时间转换成本地日期时间格式,比如IST、EST、PKT等等

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

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

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

电话:

输出:

Tue Nov 13 2012 10:15:00 GMT+0530 (India Standard Time)
Tuesday, November 13, 2012 4:45:00 AM
Invalid Date
Tuesday, November 13, 2012 4:45:00 AM
Mozilla Firefox:

电话:

输出:

Tue Nov 13 2012 10:15:00 GMT+0530 (India Standard Time)
Tuesday, November 13, 2012 4:45:00 AM
Invalid Date
Tuesday, November 13, 2012 4:45:00 AM
Safari:

电话:

输出:

Tue Nov 13 2012 10:15:00 GMT+0530 (India Standard Time)
Tuesday, November 13, 2012 4:45:00 AM
Invalid Date
Tuesday, November 13, 2012 4:45:00 AM
Internet Explorer:

电话:

输出:

Tue Nov 13 2012 10:15:00 GMT+0530 (India Standard Time)
Tuesday, November 13, 2012 4:45:00 AM
Invalid Date
Tuesday, November 13, 2012 4:45:00 AM
目前,这些是我测试的浏览器

以下是问题:


我需要一种方法将数据时间(具有类似于
2012-11-13T04:45:00.00的格式)转换为区域设置日期和时间,无论使用哪个浏览器客户端。

要在服务器上将时间转换为特定于区域设置的字符串,可以使用该方法。在该页上,请参阅关于类的“当前区域性对象”(在服务器上)的说明。确保设置正确。

简短的回答是否定的。toLocaleString可以按照开发人员的意愿实现。你的问题意味着Chrome会输出你想要的字符串

如果你想输出一致的格式,你需要使用一个单独的类库

要使用DateJS实现这一点,需要core.js中提供一些标准格式说明符,还有一些仅在extras.js中提供。文档中有一个列表

您需要的字符串是:

Tue Nov 13 2012 10:15:00 GMT+0530 (India Standard Time)
因此,要从DateJS获取此信息,您需要:

"D M d Y H:i:s \G\M\TO (e)"
DateJS的语法为:

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

我强烈建议使用日期和时间格式,而不是对所有web浏览器使用过时且执行错误的
toLocaleString()

然后,要在客户端设置日期格式,只需指定有效的区域性,然后简单地调用format函数:

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:

<script type="text/javascript" src="path_to/globalize.js"></script>
当然,更优雅的方法是在代码中创建一个属性或方法,为您编写合适的脚本,然后只引用该方法,比如:

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();
}
为什么呢?因为“g”是默认的日期格式。当您只需调用
DateTime
ToString()
方法而不使用参数(这意味着
CultureInfo.CurrentCulture
是唯一的参数……)时,就会得到这样的结果。默认格式最好,可以是短格式或长格式,也可以是其他格式,但使用此文化的人最常用

我说过,
toLocaleString()
对于所有web浏览器都是错误的。为什么呢?这是因为它将使用web浏览器设置,而不是服务器端检测到的区域性。这意味着,在同一个网页中可能存在混合文化。如果您的一些日期在服务器端格式化,而另一些日期在客户端格式化,则可能会发生这种情况。这就是为什么我们需要从服务器端传递(检测到)文化。

顺便说一句,如果您决定在web应用程序中包含“区域首选项”对话框,则不匹配的情况将更加明显,因为
toLocaleString()
不会遵循用户设置…

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

我正在从服务器接收GMT格式的数据时间,类似这样的
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
,这样就不会出现歧义


尽管如此,即使正确解释了值,也不能保证字符串在不同浏览器中的格式相同。为此,你确实需要一个图书馆。我推荐,但也有其他方法。

您最好使用库,例如并指定显式格式。仅供参考,它的行为不一致,因为输出依赖于实现(即未指定):。它有助于格式化日期,但我需要一个函数来检测客户端日期时间的本地化设置,然后将其转换为日期构造函数可以接受的任何格式@DCoderies是否有任何方法可以对所有浏览器都使用相同的方法@FelixKlingAre您能够更改从服务器检索的日期格式吗?嘿,如果您查看Globalize插件的内部,您会注意到它在内部使用ToLocalString。当我所有的整数开始在IE上以两个小数点零出现时(尽管它们在Firefox上看起来很好),我已经偶然发现了这个问题。@Martin:我相信只有在并没有设置的情况下才会发生这种情况(某种回退机制)。至少我记得是这样(我通读了这段代码)。顺便说一句,Tolocalesting(兰特)