案例一:

new Date(Date.parse("Jul 8, 2005"));

输出:

2005年7月08日上午00:00 GMT-0700 (PST)

案例二:

new Date(Date.parse("2005-07-08"));

输出:

2005 年 7 月 7 日星期四 17:00:00 GMT-0700 (PST)


为什么第二个解析不正确?


当前回答

下面是一个简短而灵活的代码片段,以跨浏览器安全的方式转换datetime-string,正如@ drinkin2112所详细描述的那样。

var inputTimestamp = "2014-04-29 13:00:15"; //example

var partsTimestamp = inputTimestamp.split(/[ \/:-]/g);
if(partsTimestamp.length < 6) {
    partsTimestamp = partsTimestamp.concat(['00', '00', '00'].slice(0, 6 - partsTimestamp.length));
}
//if your string-format is something like '7/02/2014'...
//use: var tstring = partsTimestamp.slice(0, 3).reverse().join('-');
var tstring = partsTimestamp.slice(0, 3).join('-');
tstring += 'T' + partsTimestamp.slice(3).join(':') + 'Z'; //configure as needed
var timestamp = Date.parse(tstring);

您的浏览器应该提供与Date相同的时间戳结果。解析:

(new Date(tstring)).getTime()

其他回答

两者都是正确的,但它们被解释为两个不同时区的日期。所以你比较了苹果和橘子:

// local dates
new Date("Jul 8, 2005").toISOString()            // "2005-07-08T07:00:00.000Z"
new Date("2005-07-08T00:00-07:00").toISOString() // "2005-07-08T07:00:00.000Z"
// UTC dates
new Date("Jul 8, 2005 UTC").toISOString()        // "2005-07-08T00:00:00.000Z"
new Date("2005-07-08").toISOString()             // "2005-07-08T00:00:00.000Z"

我删除了Date.parse()调用,因为它会自动用于字符串参数。我还使用ISO8601格式比较了日期,以便您可以直观地比较本地日期和UTC日期之间的日期。时间相差7小时,这就是时区的差异,这就是为什么你的测试显示了两个不同的日期。

创建这些相同的本地/UTC日期的另一种方法是:

new Date(2005, 7-1, 8)           // "2005-07-08T07:00:00.000Z"
new Date(Date.UTC(2005, 7-1, 8)) // "2005-07-08T00:00:00.000Z"

但我仍然强烈推荐Moment.js,它简单而强大:

// parse string
moment("2005-07-08").format()       // "2005-07-08T00:00:00+02:00"
moment.utc("2005-07-08").format()   // "2005-07-08T00:00:00Z"
// year, month, day, etc.
moment([2005, 7-1, 8]).format()     // "2005-07-08T00:00:00+02:00"
moment.utc([2005, 7-1, 8]).format() // "2005-07-08T00:00:00Z"

CMS接受的答案是正确的,我刚刚添加了一些功能:

修剪和清洁输入空间 解析斜杠、破折号、冒号和空格 有默认的日期和时间


// parse a date time that can contains spaces, dashes, slashes, colons
function parseDate(input) {
    // trimes and remove multiple spaces and split by expected characters
    var parts = input.trim().replace(/ +(?= )/g,'').split(/[\s-\/:]/)
    // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
    return new Date(parts[0], parts[1]-1, parts[2] || 1, parts[3] || 0, parts[4] || 0, parts[5] || 0); // Note: months are 0-based
}

下面是一个简短而灵活的代码片段,以跨浏览器安全的方式转换datetime-string,正如@ drinkin2112所详细描述的那样。

var inputTimestamp = "2014-04-29 13:00:15"; //example

var partsTimestamp = inputTimestamp.split(/[ \/:-]/g);
if(partsTimestamp.length < 6) {
    partsTimestamp = partsTimestamp.concat(['00', '00', '00'].slice(0, 6 - partsTimestamp.length));
}
//if your string-format is something like '7/02/2014'...
//use: var tstring = partsTimestamp.slice(0, 3).reverse().join('-');
var tstring = partsTimestamp.slice(0, 3).join('-');
tstring += 'T' + partsTimestamp.slice(3).join(':') + 'Z'; //configure as needed
var timestamp = Date.parse(tstring);

您的浏览器应该提供与Date相同的时间戳结果。解析:

(new Date(tstring)).getTime()

According to http://blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html the format "yyyy/mm/dd" solves the usual problems. He says: "Stick to "YYYY/MM/DD" for your date strings whenever possible. It's universally supported and unambiguous. With this format, all times are local." I've set tests: http://jsfiddle.net/jlanus/ND2Qg/432/ This format: + avoids the day and month order ambiguity by using y m d ordering and a 4-digit year + avoids the UTC vs. local issue not complying with ISO format by using slashes + danvk, the dygraphs guy, says that this format is good in all browsers.

Until the 5th edition spec came out, the Date.parse method was completely implementation dependent (new Date(string) is equivalent to Date.parse(string) except the latter returns a number rather than a Date). In the 5th edition spec the requirement was added to support a simplified (and slightly incorrect) ISO-8601 (also see What are valid Date Time Strings in JavaScript?). But other than that, there was no requirement for what Date.parse / new Date(string) should accept other than that they had to accept whatever Date#toString output (without saying what that was).

从ECMAScript 2017 (edition 8)开始,实现需要解析dat# toString和dat# toUTCString的输出,但没有指定这些字符串的格式。

截至ECMAScript 2019(版本9),日期#toString和日期#toUTCString的格式已被指定为(分别):

ddd MMM DD YYYY HH:mm:ss ZZ[(时区名)]2018年7月10日星期二18:39:58 GMT+0530(美国标准时间) ddd, DD MMM YYYY HH:mm:ss Ze.g。2018年7月10日星期二13:09:58 GMT

提供2个以上的格式,日期。Parse应该在新的实现中可靠地解析(注意,支持不是普遍存在的,不兼容的实现将继续使用一段时间)。

我建议手动解析日期字符串,并将date构造函数与年、月和日参数一起使用以避免歧义:

// parse a date in yyyy-mm-dd format
function parseDate(input) {

  let parts = input.split('-');

  // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
  return new Date(parts[0], parts[1]-1, parts[2]); // Note: months are 0-based
}