new Date() 在 Chrome 中有效,但在 Firefox 中无效
Posted
技术标签:
【中文标题】new Date() 在 Chrome 中有效,但在 Firefox 中无效【英文标题】:new Date() is working in Chrome but not Firefox 【发布时间】:2011-03-16 12:10:54 【问题描述】:我正在创建一个如下所示的日期时间字符串:2010-07-15 11:54:21
使用以下代码,我在 Firefox 中得到无效的日期,但在 Chrome 中可以正常工作
var todayDateTime = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + seconds;
var date1 = new Date(todayDateTime);
在 Firefox 中 date1 给了我一个无效的日期,但在 chrome 中它工作得很好,主要原因是什么?
【问题讨论】:
如果您想以任何方式玩它,请使用datejs.com 并非所有实现都支持 ECMA-262 中的格式,因此请始终手动解析字符串(库可以提供帮助,但对于单一格式可能不是必需的)。 现在可以在 Firefox 中使用了。 【参考方案1】:W3C specification 定义了可能的日期字符串,任何浏览器(包括 Firefox 和 Safari)都可以解析:
Year:
YYYY (e.g., 1997)
Year and month:
YYYY-MM (e.g., 1997-07)
Complete date:
YYYY-MM-DD (e.g., 1997-07-16)
Complete date plus hours and minutes:
YYYY-MM-DDThh:mmTZD (e.g., 1997-07-16T19:20+01:00)
Complete date plus hours, minutes and seconds:
YYYY-MM-DDThh:mm:ssTZD (e.g., 1997-07-16T19:20:30+01:00)
Complete date plus hours, minutes, seconds and a decimal fraction of a
second
YYYY-MM-DDThh:mm:ss.sTZD (e.g., 1997-07-16T19:20:30.45+01:00)
在哪里
YYYY = four-digit year
MM = two-digit month (01=January, etc.)
DD = two-digit day of month (01 through 31)
hh = two digits of hour (00 through 23) (am/pm NOT allowed)
mm = two digits of minute (00 through 59)
ss = two digits of second (00 through 59)
s = one or more digits representing a decimal fraction of a second
TZD = time zone designator (Z or +hh:mm or -hh:mm)
根据YYYY-MM-DDThh:mmTZD
,示例2010-07-15 11:54:21
必须转换为2010-07-15T11:54:21Z
或2010-07-15T11:54:21+02:00
(或任何其他时区)。
下面是一个简短的例子,展示了每个变体的结果:
const oldDateString = '2010-07-15 11:54:21'
const newDateStringWithoutTZD = '2010-07-15T11:54:21Z'
const newDateStringWithTZD = '2010-07-15T11:54:21+02:00'
document.getElementById('oldDateString').innerhtml = (new Date(oldDateString)).toString()
document.getElementById('newDateStringWithoutTZD').innerHTML = (new Date(newDateStringWithoutTZD)).toString()
document.getElementById('newDateStringWithTZD').innerHTML = (new Date(newDateStringWithTZD)).toString()
div
padding: 10px;
<div>
<strong>Old Date String</strong>
<br>
<span id="oldDateString"></span>
</div>
<div>
<strong>New Date String (without Timezone)</strong>
<br>
<span id="newDateStringWithoutTZD"></span>
</div>
<div>
<strong>New Date String (with Timezone)</strong>
<br>
<span id="newDateStringWithTZD"></span>
</div>
【讨论】:
【参考方案2】:这对我在Firefox
和Chrome
有效:
// The format is 'year-month-date hr:mins:seconds.milliseconds'
const d = new Date('2020-1-4 12:00:00.999')
// we use the `.` separator between seconds and milliseconds.
祝你好运……
【讨论】:
【参考方案3】:简单的解决方案,适用于所有浏览器,
var StringDate = "24-11-2017"
var DateVar = StringDate.split("-");
var DateVal = new Date(DateVar[1] + "/" + DateVar[0] + "/" + DateVar[2]);
alert(DateVal);
【讨论】:
【参考方案4】:这适用于所有浏览器 -
新日期('2001/01/31 12:00:00 AM')
new Date('2001-01-31 12:00:00')
格式:YYYY-MM-DDTHH:mm:ss.sss
详情:http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
【讨论】:
因为我们都知道这是一个国际标准。 w3.org/International/questions/qa-date-format 那么您实际上已经测试了所有浏览器?假设你有,你也知道未来所有的浏览器也会支持这种(非标准)格式? 这对我有用。所以如果你已经得到一个字符串'2001-1-31 12:00:00',我们可以简单地做:new Date(str.replace(/-/g, '/')); @JianwuChen 您故意将标准格式修改为非标准格式。不是一个好主意。 3 年后,它在 Edge 和 Window Safari 上不起作用。【参考方案5】:这也适用于大多数浏览器
new Date('2001/01/31 12:00:00')
这是格式
"yyyy/MM/dd HH:mm:ss"
【讨论】:
无法保证格式在任何浏览器中都能正常工作,更不用说“全部”了。 你说得对,答案是根据我的经验。【参考方案6】:如果您仍想使用破折号创建日期,可以使用以下格式:
var date = new Date('2013-08-31T17:00:00Z')
但请记住,它根据 UTC 创建时间。这意味着,如果您居住在 GMT+3(比 GMT 早 3 小时)时区,它会将此时区偏移量添加到时间中。所以上面的例子会有这个值,如果 GMT+3(注意是 20:00 而不是 17:00):
Sat Aug 31 2013 20:00:00 GMT+0300 (FLE Standard Time)
请务必在末尾添加“Z”字母,否则 Chrome 和 Firefox 会以不同的方式解析字符串(一个会添加时间偏移,另一个不会)。
【讨论】:
是的,如果您不提供时区,chrome 和 firefox 的行为会有所不同。而且,出于兴趣,我认为 Firefox 做错了。如果时区不存在,它应该假定 GMT。 Chrome 有,Firefox 没有。 ecma-international.org/ecma-262/5.1/#sec-15.9.1.15 @JulianJelfs—“如果不存在时区,则应假定为 GMT”,仅适用于日期(与 ISO 8601 相反)。对于日期和时间字符串,它应该假定为本地(与 ISO 8601 一致)。但无论如何,手动解析是唯一安全的方法。【参考方案7】:选项 1:
假设您的时间字符串的格式如下所示:
'2016-03-10 16:00:00.0'
在这种情况下,您可以做一个简单的正则表达式将其转换为 ISO 8601
:
'2016-03-10 16:00:00.0'.replace(/ /g,'T')
这将产生以下输出:
'2016-03-10T16:00:00.0'
这是标准的日期时间格式,因此所有浏览器都支持:
document.body.innerHTML = new Date('2016-03-10T16:00:00.0') // THIS IS SAFE TO USE
选项 2:
假设您的时间字符串的格式如下所示:
'02-24-2015 09:22:21 PM'
在这里,您可以执行以下正则表达式:
'02-24-2015 09:22:21 PM'.replace(/-/g,'/');
这也产生了所有浏览器都支持的格式:
document.body.innerHTML = new Date('02/24/2015 09:22:21 PM') // THIS IS SAFE TO USE
选项 3:
假设您有一个时间字符串,该字符串不容易调整为受良好支持的标准之一。
在这种情况下,最好将您的时间字符串分成不同的部分,并将它们用作Date
的单独参数:
document.body.innerHTML = new Date(2016, 2, 26, 3, 24, 0); // THIS IS SAFE TO USE
【讨论】:
var d = new Date('2017-08-28 08:02 PM'.replace(/-/g,'/'));这在 chrome 和 Mozilla 中都非常适合我。【参考方案8】:在使用 AngularJS 时,我在 Firefox 和 Safari 中都遇到了类似的问题。例如,如果从 Angular 返回的日期如下所示:
2014-06-02 10:28:00
使用此代码:
new Date('2014-06-02 10:28:00').toISOString();
在 Firefox 和 Safari 中返回无效日期错误。但是在 Chrome 中它工作正常。正如另一个答案所述,Chrome 很可能只是更灵活地解析日期字符串。
我的最终目标是以某种方式格式化日期。我找到了一个出色的库,可以同时处理跨浏览器兼容性问题和日期格式问题。该库称为moment.js。
使用这个库,以下代码在我测试的所有浏览器中都能正常工作:
moment('2014-06-02 10:28:00').format('MMM d YY')
如果您愿意将这个额外的库包含到您的应用程序中,您可以更轻松地构建您的日期字符串,同时避免可能的浏览器兼容性问题。作为奖励,如果需要,您将有一个很好的方法来轻松格式化、添加、减去等日期。
【讨论】:
您应该总是在解析字符串时将格式传递给moment.js,否则它只会猜测直到找到创建有效日期的格式。 【参考方案9】:我使用了以下日期格式,它适用于所有浏览器。
var target_date = new Date("Jul 17, 2015 16:55:22").getTime();
var days, hours, minutes, seconds;
var countdown = document.getElementById("countdown");
remaining = setInterval(function ()
var current_date = new Date().getTime();
var seconds_left = (target_date - current_date) / 1000;
days = parseInt(seconds_left / 86400);
seconds_left = seconds_left % 86400;
hours = parseInt(seconds_left / 3600);
seconds_left = seconds_left % 3600;
minutes = parseInt(seconds_left / 60);
seconds = parseInt(seconds_left % 60);
countdown.innerHTML = "<b>"+days + " day, " + hours + " hour, "
+ minutes + " minute, " + seconds + " second.</b>";
, 1000);
【讨论】:
【参考方案10】:实际上,Chrome 更灵活地处理不同的字符串格式。即使你不知道它的 String 格式,Chrome 仍然可以成功地将 String 转换为 Date 而不会出错。像这样:
var outputDate = new Date(Date.parse(inputString));
但对于 Firefox 和 Safari,事情变得更加复杂。其实在火狐的文档中,已经说了:(https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Date/parse)
表示 RFC2822 或 ISO 8601 日期的字符串(可以使用其他格式,但结果可能出乎意料)。
所以,当你想在 Firefox 和 Safari 中使用 Date.parse 时,你应该小心。对我来说,我用一个技巧的方法来处理它。 (注意:它可能并不总是对所有情况都正确)
if (input.indexOf("UTC") != -1)
var tempInput = inputString.substr(0, 10) + "T" + inputString.substr(11, 8) + "Z";
date = new Date(Date.parse(tempInput));
这里先将2013-08-08 11:52:18 UTC转换为2013-08-08T11:52:18Z,然后其格式为fit words在 Firefox 的文档中。此时,Date.parse 在任何浏览器中都将始终正确。
【讨论】:
【参考方案11】:在 Firefox 中,任何无效的日期都作为 Date 对象返回为 Date 1899-11-29T19:00:00.000Z
,因此检查浏览器是否为 Firefox,然后获取字符串 "1899-11-29T19:00:00.000Z".getDate()
的日期对象。最后与日期进行比较。
【讨论】:
这不是解释问题的原因,而是解释问题的结果。【参考方案12】:我遇到的一种情况是在处理毫秒时。 FF 和 IE 在尝试创建新日期时不会正确解析此日期字符串。
"2014/11/24 17:38:20.177Z"
他们不知道如何处理.177Z
。不过 Chrome 也可以。
【讨论】:
【参考方案13】:你不能以任何你想要的方式实例化一个日期对象。它必须以特定的方式。以下是一些有效的例子:
new Date() // current date and time
new Date(milliseconds) //milliseconds since 1970/01/01
new Date(dateString)
new Date(year, month, day, hours, minutes, seconds, milliseconds)
或
d1 = new Date("October 13, 1975 11:13:00")
d2 = new Date(79,5,24)
d3 = new Date(79,5,24,11,33,0)
Chrome 必须更加灵活。
来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
来自apsillers评论:
EMCAScript 规范 requires exactly one date format(即 YYYY-MM-DDTHH:mm:ss.sssZ)但 custom date formats may be freely supported by an implementation:“如果字符串不符合 [ECMAScript-defined] 格式,则函数可能回退到任何特定于实施的启发式或特定于实施的日期格式。” Chrome 和 FF 只是具有不同的“特定于实施的日期格式”。
【讨论】:
我有一个适用于所有浏览器(包括 Firefox)的解决方案:***.com/a/21984717/586051 至于为什么存在这种浏览器差异:EMCAScript 规范requires exactly one date format(即YYYY-MM-DDTHH:mm:ss.sssZ
)但custom date formats may be freely supported by an implementation:“如果字符串不符合[ECMAScript-defined ] 格式函数可以回退到任何特定于实现的启发式或特定于实现的日期格式。" Chrome 和 FF 只是具有不同的“特定于实现的日期格式”。
在 Chrome 中有效但在 Firefox 中无效的日期格式(包含“.”的月份)的一个示例:'Feb. 2019 年 14 月 14 日'
如果我将'
添加到毫秒Date('milliseconds')
,这仅对我在Firefox 中有效,否则我收到一个错误,提示未定义毫秒,但至少它有效,许多其他试验都失败了。在 Chrome 中似乎仍然很开心。【参考方案14】:
这应该适合你:
var date1 = new Date(year, month, day, hour, minute, seconds);
我必须从字符串中创建日期,所以我这样做了:
var d = '2013-07-20 16:57:27';
var date1 = new Date(d.substr(0, 4), d.substr(5, 2), d.substr(8, 2), d.substr(11, 2), d.substr(14, 2), d.substr(17, 2));
请记住,javascript 中的月份是从 0 到 11,因此您应该将月份值减 1,如下所示:
var d = '2013-07-20 16:57:27';
var date1 = new Date(d.substr(0, 4), d.substr(5, 2) - 1, d.substr(8, 2), d.substr(11, 2), d.substr(14, 2), d.substr(17, 2));
【讨论】:
以上是关于new Date() 在 Chrome 中有效,但在 Firefox 中无效的主要内容,如果未能解决你的问题,请参考以下文章
new Date() 在 Chrome 和 Firefox 中的工作方式不同