use*_*196 327 javascript date
new Date(Date.parse("Jul 8, 2005"));
Run Code Online (Sandbox Code Playgroud)
2005年7月8日星期五00:00:00 GMT-0700(太平洋标准时间)
new Date(Date.parse("2005-07-08"));
Run Code Online (Sandbox Code Playgroud)
2005年7月7日星期五17:00:00 GMT-0700(太平洋标准时间)
为什么第二个解析不正确?
CMS*_*CMS 433
在第5版规范出来之前,该Date.parse方法完全依赖于实现(new Date(string)等同于Date.parse(string)除了后者返回数字而不是a Date).在第5版规范中,添加了一个要求以支持简化(略微不正确)的 ISO-8601(另请参阅JavaScript中的有效日期时间字符串?).但除此之外,除了他们必须接受任何Date#toString输出(不说那是什么)之外,没有要求接受什么Date.parse/ new Date(string)应该接受.
从ECMAScript 2017(第8版)开始,需要实现解析Date#toString和Date#toUTCString的输出,但是没有指定这些字符串的格式.
从ECMAScript 2019(第9版)开始,Date#toString和Date#toUTCString的格式已被指定为(分别):
提供另外两种格式,Date.parse应该在新的实现中可靠地解析(注意支持不是普遍存在,不兼容的实现将在一段时间内保持使用).
我建议手动解析日期字符串,并将Date构造函数与年,月和日参数一起使用以避免歧义:
// parse a date in yyyy-mm-dd format
function parseDate(input) {
var 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
}
Run Code Online (Sandbox Code Playgroud)
dra*_*112 188
在最近编写JS解释器的经历中,我与ECMA/JS日期的内部工作进行了充分的斗争.所以,我想我会在这里投入2美分.希望分享这些内容可以帮助其他人解决浏览器在处理日期方面的差异.
所有实现在内部将它们的日期值存储为64位数字,表示自1970年1月1日UTC以来的毫秒数(GMT与UTC相同).之后出现的日期1/1/1970 00:00:00是正数和日期之前是否定的.
因此,以下代码在所有浏览器上生成完全相同的结果.
Date.parse('1/1/1970');
Run Code Online (Sandbox Code Playgroud)
在我的时区(EST)中,结果是18000000,因为这是5小时内的毫秒数(在夏令时期间只有4小时).不同时区的价值会有所不同.所有主流浏览器都以同样的方式实现.
尽管如此.虽然主要浏览器将作为日期解析的输入字符串格式存在一些差异,但就时区和夏令时而言,它们基本上将它们解释为相同.坚持的是ISO 8601格式.这是ECMA-262 v.5规范中列出的唯一格式.对于所有其他字符串格式,解释依赖于实现.具有讽刺意味的是,这是浏览器可以区分的格式.以下是我的机器上使用ISO 8601字符串格式的Chrome与Firefox在1/1/1970的比较输出.
Date.parse('1970-01-01T00:00:00Z'); // Chrome: 0 FF: 0
Date.parse('1970-01-01T00:00:00-0500'); // Chrome: 18000000 FF: 18000000
Date.parse('1970-01-01T00:00:00'); // Chrome: 0 FF: 18000000
Run Code Online (Sandbox Code Playgroud)
toString匹配我的输入值,除非我指定一个备用时区,我从来没有这样做.在没有一个符应设定本地时间输入.但是在这里它变得更糟,FF对待ISO 8601格式("YYYY-MM-DD")的缩写形式与处理长形式("YYYY-MM-DDTHH:mm:ss:sssZ")不同没有任何逻辑上的理由.这是FF的输出,具有长和短ISO日期格式,没有时区说明符.
Date.parse('1970-01-01T00:00:00'); // 18000000
Date.parse('1970-01-01'); // 0
Run Code Online (Sandbox Code Playgroud)
因此,直接回答原始提问者的问题,"YYYY-MM-DD"是ISO 8601格式的简短形式"YYYY-MM-DDTHH:mm:ss:sssZ".因此,它被解释为UTC时间,而另一个被解释为本地时间.这就是为什么,
console.log(new Date(Date.parse("Jul 8, 2005")).toString());
console.log(new Date(Date.parse("2005-07-08")).toString());
Run Code Online (Sandbox Code Playgroud)
console.log(new Date(Date.parse("Jul 8, 2005")).toString());
console.log(new Date(Date.parse("2005-07-08T00:00:00")).toString());
Run Code Online (Sandbox Code Playgroud)
底线是解析日期字符串的底线.您可以安全地在浏览器中解析的唯一ISO 8601字符串是长格式.而且,总是使用"Z"说明符.如果您这样做,您可以安全地在本地和UTC时间之间来回切换.
console.log(new Date(Date.parse("2005-07-08T00:00:00Z")).toString());
Run Code Online (Sandbox Code Playgroud)
幸运的是,大多数当前的浏览器都会平等对待其他输入格式,包括最常用的'1/1/1970'和'1/1/1970 00:00:00 AM'格式.以下所有格式(以及其他格式)在所有浏览器中都被视为本地时间输入,并在存储之前转换为UTC.因此,使它们跨浏览器兼容.此代码的输出在我的时区中的所有浏览器中都是相同的.
console.log(Date.parse("1/1/1970"));
console.log(Date.parse("1/1/1970 12:00:00 AM"));
console.log(Date.parse("Thu Jan 01 1970"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00 GMT-0500"));
Run Code Online (Sandbox Code Playgroud)
在输出端,所有浏览器都以相同的方式转换时区,但它们以不同方式处理字符串格式.以下是toString功能及其输出内容.注意我的机器上的5:00 AM toUTCString和toISOString函数输出.
打印前从UTC转换为本地时间
- toString
- toDateString
- toTimeString
- toLocaleString
- toLocaleDateString
- toLocaleTimeString
Run Code Online (Sandbox Code Playgroud)
直接打印存储的UTC时间
- toUTCString
- toISOString
Run Code Online (Sandbox Code Playgroud)
In Chrome
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString Thu Jan 01 1970
toTimeString 00:00:00 GMT-05:00 (Eastern Standard Time)
toLocaleString 1/1/1970 12:00:00 AM
toLocaleDateString 1/1/1970
toLocaleTimeString 00:00:00 AM
toUTCString Thu, 01 Jan 1970 05:00:00 GMT
toISOString 1970-01-01T05:00:00.000Z
Run Code Online (Sandbox Code Playgroud)
In Firefox
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString Thu Jan 01 1970
toTimeString 00:00:00 GMT-0500 (Eastern Standard Time)
toLocaleString Thursday, January 01, 1970 12:00:00 AM
toLocaleDateString Thursday, January 01, 1970
toLocaleTimeString 12:00:00 AM
toUTCString Thu, 01 Jan 1970 05:00:00 GMT
toISOString 1970-01-01T05:00:00.000Z
Run Code Online (Sandbox Code Playgroud)
我通常不使用ISO格式进行字符串输入.使用该格式对我有用的唯一时间是日期需要按字符串排序.ISO格式可按原样排序,而其他格式则不可排序.如果必须具有跨浏览器兼容性,请指定时区或使用兼容的字符串格式.
代码new Date('12/4/2013').toString()经历了以下内部伪转换:
"12/4/2013" -> toUCT -> [storage] -> toLocal -> print "12/4/2013"
Run Code Online (Sandbox Code Playgroud)
我希望这个答案很有帮助.
dan*_*nvk 70
疯狂有一些方法.作为一般规则,如果浏览器可以将日期解释为ISO-8601,它将会."2005-07-08"属于这个阵营,所以它被解析为UTC."2005年7月8日"不能,因此它在当地时间解析.
查看JavaScript和日期,多么糟糕!更多.
小智 7
另一种解决方案是使用日期格式构建关联数组,然后重新格式化数据.
此方法对于以不正当方式格式化的日期非常有用.
一个例子:
mydate='01.02.12 10:20:43':
myformat='dd/mm/yy HH:MM:ss';
dtsplit=mydate.split(/[\/ .:]/);
dfsplit=myformat.split(/[\/ .:]/);
// creates assoc array for date
df = new Array();
for(dc=0;dc<6;dc++) {
df[dfsplit[dc]]=dtsplit[dc];
}
// uses assc array for standard mysql format
dstring[r] = '20'+df['yy']+'-'+df['mm']+'-'+df['dd'];
dstring[r] += ' '+df['HH']+':'+df['MM']+':'+df['ss'];
Run Code Online (Sandbox Code Playgroud)
根据http://blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html格式"yyyy/mm/dd"解决了常见问题.他说:"尽可能坚持使用"YYYY/MM/DD"作为日期字符串.它得到普遍支持和明确.使用这种格式,所有时间都是本地的." 我已设置测试:http://jsfiddle.net/jlanus/ND2Qg/432/ 此格式:+通过使用ymd排序和4位数年份避免日期和月份顺序歧义+避免UTC与本地问题不对使用斜杠+ danvk符合ISO格式,dygraphs家伙说,这种格式在所有浏览器中都很好.
使用moment.js来解析日期:
var caseOne = moment("Jul 8, 2005", "MMM D, YYYY", true).toDate();
var caseTwo = moment("2005-07-08", "YYYY-MM-DD", true).toDate();
Run Code Online (Sandbox Code Playgroud)
第3个参数确定严格解析(从2.3.0开始提供).没有它,moment.js也可能会给出不正确的结果.