在JavaScript中将字符串转换为日期

jsl*_*ner 597 javascript date type-conversion

如何在JavaScript中将字符串转换为日期?

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

var dt_st= //st in date format same as dt
Run Code Online (Sandbox Code Playgroud)

Pav*_*dek 758

字符串解析的最佳字符串格式是日期ISO格式以及JavaScript Date对象构造函数.

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库,它允许使用指定的时区解析日期.

  • @Ben Taliadoros:是的,它在所有常见的浏览器中都无效,`new Date('1970-30-02')`是无效的日期,因为一年没有30个月.你不能溢出几个月但是当你溢出几天然后它在_Chrome_和_Firefox_中解析为一个有效的日期:`new Date('1970-02-30')`然后是新日期的同一天('1970-03- 02' ). (6认同)
  • Paul:感谢您提供有关IE7中的问题的信息(在IE8中也是如此),我已经更新了我的答案. (3认同)
  • 是的,我有点惊讶,因为我读到的所有内容都说使用`new Date`或`Date.parse`而没有提及兼容性问题.当我的ie7测试在整个屏幕上显示"Nan"时,想象一下我的惊喜.幸运的是,我已经在使用jquery-UI datepicker,它有一个很好的parseDate函数. (3认同)
  • 让日期解析字符串是创建Date对象的最糟糕的**方式.最好手动解析字符串并将Date作为构造函数调用.某些浏览器会将没有时区的ISO字符串视为UTC,其他浏览器则视为本地. (3认同)
  • @Amos:注意字母 T,它分隔日期和时间。如果您编写“new Date('2011-04-11T11:51:00')”,则创建的日期有效。 (2认同)

Rom*_*nov 261

不幸的是我发现了

var mydate = new Date('2014-04-03');
console.log(mydate.toDateString());
Run Code Online (Sandbox Code Playgroud)

返回"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());
Run Code Online (Sandbox Code Playgroud)

  • 它根本不是疯了,调整很可能是由[DST](http://en.wikipedia.org/wiki/Daylight_saving_time)引起的.日期为`yyyy-MM-dd`的日期被解析为UTC和[toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toString)返回*local*时间,因此根据用户的时区,它肯定会返回不同的结果.如果总是希望时间为UTC,则应使用[toUTCString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toUTCString). (38认同)
  • 一种解压参数的好方法 `var [YYYY, MM, DD] = '2014-04-03'.split('-')` (5认同)
  • @AdamYoungers由于Javascript从0开始计算月份:1月 - 0月,2月1日等 (4认同)
  • 像这样的小块使StackOverflow成为一个可行的资源.当然,你可以从http://stackoverflow.com/a/7091965/5076162找到一个非常好的答案,但这是额外的锦上添花; 这是在一个完全独立的线程中找到的.结合这两个,瞧!坚实的年龄计算器. (4认同)
  • 仅仅因为有一个解释并不意味着它不是疯了.声称日期处理很简单并且不能跨计算平台进行大量分歧处理将是一个谎言. (4认同)

小智 115

var st = "26.04.2013";
var pattern = /(\d{2})\.(\d{2})\.(\d{4})/;
var dt = new Date(st.replace(pattern,'$3-$2-$1'));
Run Code Online (Sandbox Code Playgroud)

输出将是:

dt => Date {Fri Apr 26 2013}
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,这个解决方案存在问题.详情请访问:http://stackoverflow.com/questions/17959660/todatestring-decrements-my-date (4认同)

小智 78

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","-")
Run Code Online (Sandbox Code Playgroud)

  • 处理每个变体的日期,而不仅仅是美国格式 (3认同)
  • @MarkJones不信任`.indexOf()`方法,因为没有polyfils它不是跨浏览器兼容的.相反,使用更兼容的`.match()`或`.test()`vanilla JS方法. (3认同)
  • 在函数开头添加 var _delimiter = _format.match(/\W/g)[0]; 可以自动获取分隔符并排除第三个参数。 (2认同)

obl*_*lig 37

将它作为参数传递给Date():

var st = "date in some format"
var dt = new Date(st);
Run Code Online (Sandbox Code Playgroud)

您可以使用以下方式访问日期,月份和年份:dt.getMonth().

  • 我做`console.log(new Date('30 -08-2018'))`并得到无效的日期 (6认同)
  • 这个答案忽略了这个问题的多种复杂性,例如,如果我在我的计算机(在英国)上对日期“01/02/2020”执行此操作,它将返回 2 月 1 日,就好像在美国做了同样的事情一样将于 1 月 2 日回归。您几乎不应该使用这种幼稚的实现。请改用 [moment](/sf/answers/2509358771/)。 (4认同)

Jua*_*edo 30

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

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

moment("12-25-1995", "MM-DD-YYYY");
Run Code Online (Sandbox Code Playgroud)

你可以检查一个日期是否有效.

moment("not a real date").isValid(); //Returns false
Run Code Online (Sandbox Code Playgroud)

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

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


H6.*_*H6. 21

如果您可以使用极好的时刻库(例如在Node.js项目中),您可以使用例如轻松解析日期

var momentDate = moment("2014-09-15 09:00:00");
Run Code Online (Sandbox Code Playgroud)

并可以通过访问JS日期对象

momentDate ().toDate();
Run Code Online (Sandbox Code Playgroud)

  • 请注意,没有节点的那一刻工作得很好 (3认同)

Tor*_*ker 18

new Date(2000, 10, 1) 会给你"Wed Wed 01 2000 00:00:00 GMT + 0100(CET)"

看到0月份给你一月


Cla*_*lim 17

在我看来,这是最好、最简单的解决方案:

只需将日期字符串(使用ISO 格式)与“T00:00:00”连接起来,然后使用JavaScript Date() 构造函数,如下例所示。

const dateString = '2014-04-03'
var mydate = new Date(dateString + "T00:00:00");
console.log(mydate.toDateString());
Run Code Online (Sandbox Code Playgroud)

关于上述解决方案的一些细节(但可选阅读):

在 ISO 格式中,如果您提供时间并且 Z 未出现在字符串末尾,则日期将是本地时区而不是 UTC 时区。这意味着,当以这种方式设置日期时,如果不指定时区,JavaScript 将使用本地浏览器的时区。当获取日期时,如果不指定时区,结果也会转换为浏览器的时区。而且, 默认情况下,JavaScript 中的几乎每个日期方法(除了一个)也会为您提供本地时区的日期/时间(如果您指定 UTC,则只能获得 UTC)。因此,在本地/浏览器时区中使用您可能不会得到不需要的结果,因为本地/浏览器时区和 UTC 时区之间存在差异,这是日期字符串转换的主要问题之一。但如果您要使用此解决方案,请了解您的背景并了解您在做什么。另请注意,在日期时间字符串中省略 T 或 Z可能会在不同的浏览器中产生不同的结果。

重要的是要注意,上面的示例将为您提供与下面的示例完全相同的返回值,这是该问题中得票第二多的答案:

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());
Run Code Online (Sandbox Code Playgroud)

主要区别在于,这里提供的第一个示例比第二个示例更简单,甚至更防错(至少在我看来,如下所述)。

因为如果您仅使用 ISO 格式的一个日期字符串参数(第一个示例)调用JavaScript Date() 构造函数date,它不接受高于其逻辑限制的值(因此,如果您指定 13 作为月份或 32 作为日期,您会收到无效日期)。

但是,当您使用具有多个日期参数的相同构造函数(第二个示例)时,高于逻辑限制的参数将调整为相邻值,并且您不会收到无效日期错误(因此,如果您给出 13 作为月份,它将调整为 1,而不是给您一个无效日期)。

或者替代(和第三)解决方案将两者混合,使用第一个示例只是为了验证日期字符串,如果它有效,则使用第二个示例(这样您就可以避免第一个示例的浏览器可能不一致,同时避免高于第二个示例的逻辑限制的参数的权限)。

像这样(也接受部分日期):

function covertStringToDate(dateString) {
    //dateString should be in ISO format: "yyyy-mm-dd", "yyyy-mm" or "yyyy"
    if(new Date(dateString).toString() === "Invalid Date") {
        return false
    } else {
        const onlyNumbers = dateString.replace(/\D/g, ""); 
        const year = onlyNumbers.slice(0,4) 
        const month = onlyNumbers.slice(4,6)
        const day = onlyNumbers.slice(6,8)
        if(!month){
            return(new Date(year))
        } else if (!day) {
            return(new Date(year, month - 1))
        } else {
            return(new Date(year, month - 1, day))
        }        
    }
}
Run Code Online (Sandbox Code Playgroud)

第四种选择(也是最后一个建议)是使用适当的第三个库(如momentdate-fns

参考:


Ari*_*tos 16

对于那些正在寻找一个小巧聪明的解决方案的人:

String.prototype.toDate = function(format)
{
  var normalized      = this.replace(/[^a-zA-Z0-9]/g, '-');
  var normalizedFormat= format.toLowerCase().replace(/[^a-zA-Z0-9]/g, '-');
  var formatItems     = normalizedFormat.split('-');
  var dateItems       = normalized.split('-');

  var monthIndex  = formatItems.indexOf("mm");
  var dayIndex    = formatItems.indexOf("dd");
  var yearIndex   = formatItems.indexOf("yyyy");
  var hourIndex     = formatItems.indexOf("hh");
  var minutesIndex  = formatItems.indexOf("ii");
  var secondsIndex  = formatItems.indexOf("ss");

  var today = new Date();

  var year  = yearIndex>-1  ? dateItems[yearIndex]    : today.getFullYear();
  var month = monthIndex>-1 ? dateItems[monthIndex]-1 : today.getMonth()-1;
  var day   = dayIndex>-1   ? dateItems[dayIndex]     : today.getDate();

  var hour    = hourIndex>-1      ? dateItems[hourIndex]    : today.getHours();
  var minute  = minutesIndex>-1   ? dateItems[minutesIndex] : today.getMinutes();
  var second  = secondsIndex>-1   ? dateItems[secondsIndex] : today.getSeconds();

  return new Date(year,month,day,hour,minute,second);
};
Run Code Online (Sandbox Code Playgroud)

例:

"22/03/2016 14:03:01".toDate("dd/mm/yyyy hh:ii:ss");
"2016-03-29 18:30:00".toDate("yyyy-mm-dd hh:ii:ss");
Run Code Online (Sandbox Code Playgroud)

  • 弄乱 String.prototype 不是一个好主意,它可能会导致很难找到错误 (2认同)
  • 确实,搞乱 String.prototype 并不是一个好主意,但是这个基础对我帮助很大。我将它形成一个函数来保存。 (2认同)

Ale*_* N. 11

如果你想转换格式"dd/MM/yyyy".这是一个例子:

var pattern = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
var arrayDate = stringDate.match(pattern);
var dt = new Date(arrayDate[3], arrayDate[2] - 1, arrayDate[1]);
Run Code Online (Sandbox Code Playgroud)

此解决方案适用于小于9的IE版本.


Luc*_*oni 11

时间戳应该转换为数字

var ts = '1471793029764';
ts = Number(ts); // cast it to a Number
var date = new Date(ts); // works

var invalidDate = new Date('1471793029764'); // does not work. Invalid Date
Run Code Online (Sandbox Code Playgroud)


Mar*_*ahn 10

只是 new Date(st);

假设它是正确的格式.

  • 不,这是一个糟糕的主意,除非您确定输入始终采用 Date 能够正确解析的格式。它将在世界各地爆发。 (2认同)
  • @JulianKnight - 我*字面上说*“假设它的格式正确”。不,它不会在世界各地出现故障,哈哈 (2认同)
  • 那你就没有真正回答问题。请将您的答案与已接受的答案进行比较。在很多情况下你的答案都会被打破。怎么样 `new Date("3/2/20")` - 这会给你带来什么?你认为它会给我带来同样的答案吗?除非我们在同一个国家,否则几乎肯定不会。正如我所说,这是一个糟糕的主意。讽刺并不能使事情变得正确。 (2认同)

nik*_*svp 9

Date.parse几乎可以得到你想要的东西.它在am/ pmpart 上窒息,但是通过一些黑客你可以让它工作:

var str = 'Sun Apr 25, 2010 3:30pm',
    timestamp;

timestamp = Date.parse(str.replace(/[ap]m$/i, ''));

if(str.match(/pm$/i) >= 0) {
    timestamp += 12 * 60 * 60 * 1000;
}
Run Code Online (Sandbox Code Playgroud)


z33*_*33m 7

看看datejs图书馆http://www.datejs.com/


Mar*_*ças 7

转换为 pt-BR 格式:

    var dateString = "13/10/2014";
    var dataSplit = dateString.split('/');
    var dateConverted;

    if (dataSplit[2].split(" ").length > 1) {

        var hora = dataSplit[2].split(" ")[1].split(':');
        dataSplit[2] = dataSplit[2].split(" ")[0];
        dateConverted = new Date(dataSplit[2], dataSplit[1]-1, dataSplit[0], hora[0], hora[1]);

    } else {
        dateConverted = new Date(dataSplit[2], dataSplit[1] - 1, dataSplit[0]);
    }
Run Code Online (Sandbox Code Playgroud)

我希望对某人有所帮助!!!


小智 6

对于 ?onverting string to date in js 我使用 http://momentjs.com/

moment().format('MMMM Do YYYY, h:mm:ss a'); // August 16th 2015, 4:17:24 pm
moment().format('dddd');                    // Sunday
moment().format("MMM Do YY");               // Aug 16th 15
moment().format('YYYY [escaped] YYYY');     // 2015 escaped 2015
moment("20111031", "YYYYMMDD").fromNow(); // 4 years ago
moment("20120620", "YYYYMMDD").fromNow(); // 3 years ago
moment().startOf('day').fromNow();        // 16 hours ago
moment().endOf('day').fromNow();          // in 8 hours
Run Code Online (Sandbox Code Playgroud)


小智 5

我为此创建了一个小提琴,您可以在任何日期字符串上使用toDate()函数并提供日期格式。这将返回一个Date对象。 https://jsfiddle.net/Sus​​hil231088/q56yd0rp/

"17/9/2014".toDate("dd/MM/yyyy", "/")
Run Code Online (Sandbox Code Playgroud)

  • 搞乱 String.prototype 很可能会以泪水告终。 (4认同)

And*_*ndy 5

我创建了这个函数来将任何 Date 对象转换为 UTC Date 对象。

function dateToUTC(date) {
    return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
}


dateToUTC(new Date());
Run Code Online (Sandbox Code Playgroud)


dpa*_*tru 5

这个答案基于 Kassem 的答案,但它也处理两位数的年份。我提交了对 Kassem 答案的编辑,但如果未获批准,我也会将此作为单独的答案提交。

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 year = parseInt(dateItems[yearIndex]); 
        // adjust for 2 digit year
        if (year < 100) { year += 2000; }
        var month=parseInt(dateItems[monthIndex]);
        month-=1;
        var formatedDate = new Date(year,month,dateItems[dayIndex]);
        return formatedDate;
}

stringToDate("17/9/14","dd/MM/yyyy","/");
stringToDate("17/9/2014","dd/MM/yyyy","/");
stringToDate("9/17/2014","mm/dd/yyyy","/")
stringToDate("9-17-2014","mm-dd-yyyy","-")
Run Code Online (Sandbox Code Playgroud)


Kam*_*ski 5

表现

今天(2020.05.08)我对选定的解决方案进行了测试 - 对于两种情况:输入日期是 ISO8601 字符串(Ad、Bd、Cd、Dd、Ed),输入日期是时间戳(At、Ct、Dt)。解决方案 Bd,Cd,Ct 不会将 js Date 对象作为结果返回,但我添加它们是因为它们可能很有用,但我不会将它们与有效解决方案进行比较。此结果可用于大量日期解析。

结论

  • new Date对于所有浏览器的 ISO 日期和时间戳,解决方案(Ad) 比 moment.js (Dd) 快 50-100 倍
  • 解决方案new Date(Ad) 比parseDate(Ed)快约 10 倍
  • Date.parse如果我们需要从所有浏览器上的 ISO 日期获取时间戳,则解决方案(Bd) 是最快的

在此处输入图片说明

细节

我在 Chrome 81.0、Safari 13.1、Firefox 75.0 上对 MacOs High Sierra 10.13.6 进行了测试。解决方案parseDate(Ed) 使用new Date(0)并手动设置 UTC 日期组件。

let ds = '2020-05-14T00:00Z'; // Valid ISO8601 UTC date
let ts = +'1589328000000';    // timestamp

let Ad = new Date(ds);
let Bd = Date.parse(ds);
let Cd = moment(ds);
let Dd = moment(ds).toDate();
let Ed = parseDate(ds);

let At = new Date(ts);
let Ct = moment(ts);
let Dt = moment(ts).toDate();

log = (n,d) => console.log(`${n}: ${+d} ${d}`);

console.log('from date string:', ds)
log('Ad', Ad);
log('Bd', Bd);
log('Cd', Cd);
log('Dd', Dd);
log('Ed', Ed);
console.log('from timestamp:', ts)
log('At', At);
log('Ct', Ct);
log('Dt', Dt);



function parseDate(dateStr) {
  let [year,month,day] = dateStr.split(' ')[0].split('-');
  let d=new Date(0);
  d.setUTCFullYear(year);
  d.setUTCMonth(month-1);
  d.setUTCDate(day)
  return d;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment-with-locales.min.js"></script>

This snippet only presents used soultions  
Run Code Online (Sandbox Code Playgroud)

铬的结果

在此处输入图片说明


归档时间:

查看次数:

1640147 次

最近记录:

6 年,1 月 前