【问题标题】:IE's toLocaleString has strange characters in resultsIE 的 toLocaleString 结果中有奇怪的字符
【发布时间】:2014-08-29 19:26:40
【问题描述】:

我在日期的toLocaleString 中遇到了一个非常奇怪的事情,显然是特定于 IE 的。

在 IE 控制台窗口中:

new Date("2014-08-28T20:51:09.9190106Z").toLocaleString();
"‎8‎/‎28‎/‎2014‎ ‎1‎:‎51‎:‎09‎ ‎PM"

现在,手动输入该字符串作为字符串并将其与方法返回的内容进行比较:

"8/28/2014 1:51:09 PM" === new Date("2014-08-28T20:51:09.9190106Z").toLocaleString();
false

有谁知道为什么在 IE 中会发生这种情况?这在 Chrome 中不会发生。

更新:更多示例:

new Date("8/28/2014 1:51:09 PM")
[date] Thu Aug 28 2014 13:51:09 GMT-0700 (Pacific Daylight Time)[date] Thu Aug 28 2014 13:51:09 GMT-0700 (Pacific Daylight Time)

new Date(new Date("2014-08-28T20:51:09.9190106Z").toLocaleString())
[date] Invalid Date[date] Invalid Date

【问题讨论】:

标签: javascript internet-explorer


【解决方案1】:

使用

Str.replace(/[^ -~]/g,'')

这将删除不需要的特殊字符。

【讨论】:

  • 这还不错,但 März 现在是 Mrz,在德国是有效的月份名称
  • 对 IE 错误的超赞 hack :)
【解决方案2】:

首先,一些背景知识:IE11 实现了 ECMA-402 ECMAScript 国际化 API,该 API 将 Date.prototype.toLocaleString(以及 toLocaleDateStringtoLocaleTimeString)重新定义为在 Intl.DateTimeFormat 上对 format 的调用。因此,d.toLocaleString() 相当于

Intl.DateTimeFormat(undefined, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
}).format(d)

您可能认为这是非常明确的,但浏览器在它们支持的格式以及构成格式的字符方面有很大的余地。这是设计使然 - 对于全球所有语言环境和语言,指定这将是相当繁重的并且很难保持最新状态。出于这个原因,您不能期望能够跨浏览器比较toLocaleString 的结果,甚至不能指望同一个浏览器在不同版本之间继续给出相同的结果。随着底层语言环境数据发生变化(可能是因为本地自定义发生了变化,或者有更多数据可用,或者添加了更好的格式),从这个 API 返回的格式也会发生变化。

从中得出的结论是,您应该尽量不要依赖将toLocaleString API 的输出与应用程序中的某些静态值进行比较。此外,给定日期dDate.parse(d.toLocaleString()) 有时可能会起作用,但有时会不起作用,这取决于语言环境,因此最好也避免这种情况。

话虽如此,en-US 相对稳定,并且在大多数情况下,浏览器(目前)同意基本格式是什么。但是,IE 在日期周围插入双向控制字符。这是设计使然,因此输出文本在与其他文本连接时将正确流动。这在混合 LTR 和 RTL 内容时尤其重要,例如将格式化的 RTL 日期与 LTR 文本连接。

【讨论】:

  • 这就是我们最终要做的事情,首先将我们的测试更改为不依赖于 toLocaleString 的特定输出,然后在我们的淘汰赛模板绑定中只使用 toLocaleString 而不是在代码本身,并将日期对象作为实际日期保留在代码的其余部分中。
【解决方案3】:

原来你看不到它们,但 IE 的 Date.toLocaleString 显然包含从左到右的标记 (U+200E):

8<200E>/<200E>21<200E>/2014<200E> <200E> 9<200E>:<200E>16<200E>:<200E>:18<200E> <200E>AM

太棒了。我想是时候向 IE 提交 bug 了?

【讨论】:

  • IE 团队通过电子邮件参与。如果我得到更多信息,将更新此内容。
  • IE 团队的 brian 添加了更具体的答案,因此我的答案不再是最佳答案 :)
【解决方案4】:

请看http://jsbin.com/mehowehase/1/edit?html,js,console

var dt = new Date();
var x = dt.toLocaleDateString();
console.log("length : "+x.length);
var arr = x.split("/");
console.log("month : "+parseInt(arr[0],10));

上面x的长度在IE中是14,而在其他浏览器中是9。这支持 John 的评论,即 IE 正在添加从左到右的标记。这在我看来绝对是一个错误。

【讨论】:

  • 我们认为这是一个错误,IE/Edge 团队实际上是在上面做出回应的,并且“您可能认为这非常明确,但浏览器对于什么格式有很大的余地他们支持以及哪些字符构成了格式。这是设计使然 - 对于全球所有的语言环境和语言,指定这将是相当繁重的,并且很难保持最新状态。”
【解决方案5】:

我在我的 IE11 中没有看到这一点,因此它可能与您在 IE 或您的机器中的设置/配置有关。对我来说,结果是:

"‎28‎/‎08‎/‎2014‎ ‎21‎:‎51‎:‎09" === new Date("2014-08-28T20:51:09.9190106Z").toLocaleString(); true

您是否复制粘贴了从网页传递给构造函数的日期字符串?

我认为 IE 团队在这个阶段不会接受它作为一个错误,因为它没有明确的重现步骤

【讨论】:

  • 考虑到我在哪里工作,他们可能会接受 :) 我们可以使用 IE 等在 QUnit 的单元测试中重现这一点,我们组织中的每个人都可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-26
  • 2014-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多