在 JavaScript 中将字符串解析为日期

IT技术 javascript date date-parsing
2021-01-04 00:45:57

如何在 JavaScript 中将字符串转换为 Date 对象?

var st = "date in some format"
var dt = new Date();

var dt_st = // st in Date format, same as dt.
6个回答

字符串解析的最佳字符串格式是日期 ISO 格式和 JavaScript 日期对象构造函数。

ISO 格式示例:YYYY-MM-DDYYYY-MM-DDTHH:MM:SS.

可是等等! 仅使用“ISO 格式”本身并不能可靠地工作。字符串有时被解析为 UTC,有时被解析为本地时间(基于浏览器供应商和版本)。最佳实践应始终将日期存储为 UTC,并将计算作为 UTC。

要将日期解析为 UTC,请附加Z - 例如:new Date('2011-04-11T10:20:30Z')

要以 UTC 显示日期,请使用.toUTCString()
要以用户本地时间显示日期,请使用.toString()

有关MDN 的更多信息| 日期这个答案

对于旧的 Internet Explorer 兼容性(小于 9 的 IE 版本不支持 Date 构造函数中的 ISO 格式),您应该将日期时间字符串表示拆分为它的部分,然后您可以使用使用日期时间部分的构造函数,例如: new Date('2011', '04' - 1, '11', '11', '51', '00'). 请注意,月份数必须少 1。


替代方法 - 使用适当的库:

您还可以利用Moment.js来解析指定时区的日期。

对于 Paul Tomblin 提出的相同“Nan”问题,我还必须对 safari 使用“拆分字符串”方法。new Date('2011-04-11 11:51:00') 将返回“无效日期”。
2021-02-08 00:45:57
@Ben Taliadoros:是的,它在所有常见浏览器中new Date('1970-30-02')都无效,日期无效,因为一年没有 30 个月。您不能溢出月份,但是当您溢出天数时,它会在ChromeFirefox 中解析为有效日期:new Date('1970-02-30')然后与 new Date('1970-03-02') 是同一天。
2021-02-08 00:45:57
不幸的是,我遇到了* 它不适用于所有用户的问题
2021-02-25 00:45:57
让 Date 解析字符串是创建 Date 对象最糟糕的方式。手动解析字符串并调用 Date 作为构造函数要好得多。一些浏览器会将没有时区的 ISO 字符串视为 UTC,其他浏览器则视为本地。
2021-02-28 00:45:57
@Amos:请注意分隔日期和时间的字母 T。如果你写new Date('2011-04-11T11:51:00')的日期创建是有效的。
2021-03-05 00:45:57

不幸的是我发现

var mydate = new Date('2014-04-03');
console.log(mydate.toDateString());

返回“2014 年 4 月 2 日星期三”。我知道这听起来很疯狂,但它发生在某些用户身上。

防弹解决方案如下:

var parts ='2014-04-03'.split('-');
// Please pay attention to the month (parts[1]); JavaScript counts months from 0:
// January - 0, February - 1, etc.
var mydate = new Date(parts[0], parts[1] - 1, parts[2]); 
console.log(mydate.toDateString());

这个答案表明示例中的行为是不正确的。根据规范:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...(参见:datestring)示例中的输出值是正确的
2021-02-07 00:45:57
一直在敲我的头。这似乎有效,但我不明白您为什么使用部件 [0]-1 而不仅仅是部件 [0]。
2021-02-17 00:45:57
一点也不疯狂,调整很可能是由DST 开始引起的。 格式的日期yyyy-MM-dd被解析为 UTC 和toString返回本地时间,因此根据用户时区,它绝对可以返回不同的结果。如果总是希望时间为 UTC,那么您应该使用toUTCString
2021-02-21 00:45:57
解压参数的好方法 var [YYYY, MM, DD] = '2014-04-03'.split('-')
2021-02-24 00:45:57
@AdamYoungers 由于 Javascript 从 0 开始计算月份:1 月 - 0、2 月 - 1 等
2021-03-04 00:45:57
var st = "26.04.2013";
var pattern = /(\d{2})\.(\d{2})\.(\d{4})/;
var dt = new Date(st.replace(pattern,'$3-$2-$1'));

输出将是:

dt => Date {Fri Apr 26 2013}
输出未知,因为您的代码既不将任何内容转换为字符串,也不输出任何内容。
2021-02-14 00:45:57
这实际上将在 4 月 25 日星期五返回
2021-03-03 00:45:57
不幸的是,此解决方案存在问题。详情请见:stackoverflow.com/questions/17959660/...
2021-03-09 00:45:57
function stringToDate(_date,_format,_delimiter)
{
            var formatLowerCase=_format.toLowerCase();
            var formatItems=formatLowerCase.split(_delimiter);
            var dateItems=_date.split(_delimiter);
            var monthIndex=formatItems.indexOf("mm");
            var dayIndex=formatItems.indexOf("dd");
            var yearIndex=formatItems.indexOf("yyyy");
            var month=parseInt(dateItems[monthIndex]);
            month-=1;
            var formatedDate = new Date(dateItems[yearIndex],month,dateItems[dayIndex]);
            return formatedDate;
}

stringToDate("17/9/2014","dd/MM/yyyy","/");
stringToDate("9/17/2014","mm/dd/yyyy","/")
stringToDate("9-17-2014","mm-dd-yyyy","-")
处理来自每个变体的日期,而不仅仅是美国格式
2021-02-07 00:45:57
@MarkJones 不要相信该.indexOf()方法,因为它在没有 polyfils 的情况下不能跨浏览器兼容。相反,使用更兼容的.match().test()原版的 JS 方法。
2021-02-21 00:45:57
这个日期格式是错误的。这是因为mm是几分钟而不是几个月......在你的格式中使用 MM
2021-02-23 00:45:57
var _delimiter = _format.match(/\W/g)[0];在函数的开头添加,您可以自动获取分隔符和第三个参数的前置。
2021-03-02 00:45:57

moment.js ( http://momentjs.com/ ) 是一个完整的使用日期包并且支持ISO 8601 字符串

您可以添加字符串日期和格式。

moment("12-25-1995", "MM-DD-YYYY");

您可以检查日期是否有效。

moment("not a real date").isValid(); //Returns false

一些显示示例

let dt = moment("02-01-2019", "MM-DD-YYYY");
console.log(dt.fromNow()+' |'+dt.format('LL')) 
// output: "3 months ago | February 1, 2019"

请参阅文档 http://momentjs.com/docs/#/parsing/string-format/

建议:我建议使用包含很多格式的日期的包,因为时区和格式时间管理真的是一个大问题,moment js解决了很多格式。您可以轻松地从一个简单的字符串解析日期,但我认为这是一项艰巨的工作,可以支持所有格式和日期变体。

一些显示示例 let dt = moment("02-01-2019", "MM-DD-YYYY");console.log(dt.fromNow()+' | '+dt.format('LL'))输出:“3 个月前 | 2019 年 2 月 1 日”
2021-03-06 00:45:57