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

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

var st = "date in some format"var dt = new Date();
var dt_st = // st in Date format, same as dt.
2680173 次浏览

只是new Date(st);

假设它是适当格式

new Date(2000, 10, 1)将显示“Wed Nov 01 2000 00:00:00 GMT+0100(CET)”

看到0的月份给你一月

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

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

您可以访问日期、月份、年份,例如:dt.getMonth()

Date.parse几乎让你得到你想要的。它在am/pm部分窒息,但通过一些黑客攻击,你可以让它工作:

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;}

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

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

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

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

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

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

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


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

您还可以利用库Moment.js,它允许解析具有指定时区的日期。

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}

不幸的是我发现

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

返回“Wed Apr 02 2014”。我知道这听起来很疯狂,但它会发生在一些用户身上。

防弹溶液如下:

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());

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","-")

如果你可以使用很棒的卢克松库,你可以很容易地解析你的日期。

var luxonDate = DateTime.fromISO("2014-09-15T09:00:00");

并且可以通过以下方式访问JS日期对象

luxonDate().toJSDate();

使用的旧答案MomentJS

var momentDate = moment("2014-09-15 09:00:00");momentDate ().toDate();

使用此格式…

//get current date in javascript
var currentDate = new Date();

// for getting a date from a textbox as string format
var newDate=document.getElementById("<%=textBox1.ClientID%>").value;
// convert this date to date time
var MyDate = new Date(newDate);

ISO 8601类型的日期字符串,尽管标准非常优秀,但仍未得到广泛支持。

这是一个很好的资源来确定您应该使用哪种日期字符串格式:

是的,这意味着您的日期字符串可以像

"2014/10/13 23:57:52"而不是"2014-10-13 23:57:52"

转换为格式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]);}

希望能帮到大家!!!

var date = new Date(year, month, day);

var date = new Date('01/01/1970');

格式为'01-01-1970'的日期字符串在FireFox中不起作用,因此在日期格式字符串中最好使用“/”而不是“-”。

你也可以这样做:mydate.toLocaleDateString();

                //little bit of code for Converting dates
var dat1 = document.getElementById('inputDate').value;var date1 = new Date(dat1)//converts string to date objectalert(date1);var dat2 = document.getElementById('inputFinishDate').value;var date2 = new Date(dat2)alert(date2);

如果您想从格式“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]);

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

对于在js中将字符串转换为日期,我使用http://momentjs.com/

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

如果您需要在转换为Date格式之前检查字符串的内容:

// Convert 'M/D/YY' to Date()mdyToDate = function(mdy) {var d = mdy.split(/[\/\-\.]/, 3);
if (d.length != 3) return null;
// Check if date is validvar mon = parseInt(d[0]),day = parseInt(d[1]),year= parseInt(d[2]);if (d[2].length == 2) year += 2000;if (day <= 31 && mon <= 12 && year >= 2015)return new Date(year, mon - 1, day);
return null;}

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

更新:现在不建议使用,一个很好的替代时刻是datefnshttps://date-fns.org/


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/

var a = "13:15"var b = toDate(a, "h:m")//alert(b);document.write(b);
function toDate(dStr, format) {var now = new Date();if (format == "h:m") {now.setHours(dStr.substr(0, dStr.indexOf(":")));now.setMinutes(dStr.substr(dStr.indexOf(":") + 1));now.setSeconds(0);return now;} elsereturn "Invalid Format";}

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

"17/9/2014".toDate("dd/MM/yyyy", "/")

对于那些正在寻找小型智能解决方案的人:

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);};

示例:

"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");

时间戳应投射到一个数字

var ts = '1471793029764';ts = Number(ts); // cast it to a Numbervar date = new Date(ts); // works
var invalidDate = new Date('1471793029764'); // does not work. Invalid Date

另一种方法来做到这一点:

String.prototype.toDate = function(format) {format = format || "dmy";var separator = this.match(/[^0-9]/)[0];var components = this.split(separator);var day, month, year;for (var key in format) {var fmt_value = format[key];var value = components[key];switch (fmt_value) {case "d":day = parseInt(value);break;case "m":month = parseInt(value)-1;break;case "y":year = parseInt(value);}}return new Date(year, month, day);};a = "3/2/2017";console.log(a.toDate("dmy"));// Date 2017-02-03T00:00:00.000Z

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

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

dateToUTC(new Date());

使用此代码:(我的问题用此代码解决了)

function dateDiff(date1, date2){var diff = {}                           // Initialisation du retourvar tmp = date2 - date1;
tmp = Math.floor(tmp/1000);             // Nombre de secondes entre les 2 datesdiff.sec = tmp % 60;                    // Extraction du nombre de secondes
tmp = Math.floor((tmp-diff.sec)/60);    // Nombre de minutes (partie entière)diff.min = tmp % 60;                    // Extraction du nombre de minutes
tmp = Math.floor((tmp-diff.min)/60);    // Nombre d'heures (entières)diff.hour = tmp % 24;                   // Extraction du nombre d'heures
tmp = Math.floor((tmp-diff.hour)/24);   // Nombre de jours restantsdiff.day = tmp;
return diff;

}

我创建了parseDateTime函数将字符串转换为日期对象,它在所有浏览器(包括IE浏览器)中工作,检查是否有人需要,参考https://github.com/Umesh-Markande/Parse-String-to-Date-in-all-browser

    function parseDateTime(datetime) {var monthNames = ["January", "February", "March","April", "May", "June", "July","August", "September", "October","November", "December"];if(datetime.split(' ').length == 3){var date = datetime.split(' ')[0];var time = datetime.split(' ')[1].replace('.00','');var timearray = time.split(':');var hours = parseInt(time.split(':')[0]);var format = datetime.split(' ')[2];var bits = date.split(/\D/);date = new Date(bits[0], --bits[1], bits[2]); /* if you change format of datetime which is passed to this function, you need to change bits e.x ( bits[0], bits[1], bits[2 ]) position as per date, months and year it represent bits array.*/var day = date.getDate();var monthIndex = date.getMonth();var year = date.getFullYear();if ((format === 'PM' || format === 'pm') && hours !== 12) {hours += 12;try{  time = hours+':'+timearray[1]+':'+timearray[2] }catch(e){ time = hours+':'+timearray[1] }}var formateddatetime = new Date(monthNames[monthIndex] + ' ' + day + '  ' + year + ' ' + time);return formateddatetime;}else if(datetime.split(' ').length == 2){var date = datetime.split(' ')[0];var time = datetime.split(' ')[1];var bits = date.split(/\D/);var datetimevalue = new Date(bits[0], --bits[1], bits[2]); /* if you change format of datetime which is passed to this function, you need to change bits e.x ( bits[0], bits[1], bits[2 ]) position as per date, months and year it represent bits array.*/var day = datetimevalue.getDate();var monthIndex = datetimevalue.getMonth();var year = datetimevalue.getFullYear();var formateddatetime = new Date(monthNames[monthIndex] + ' ' + day + '  ' + year + ' ' + time);return formateddatetime;}else if(datetime != ''){var bits = datetime.split(/\D/);var date = new Date(bits[0], --bits[1], bits[2]); /* if you change format of datetime which is passed to this function, you need to change bits e.x ( bits[0], bits[1], bits[2 ]) position as per date, months and year it represent bits array.*/return date;}return datetime;}
var date1 = '2018-05-14 05:04:22 AM';   // yyyy-mm-dd hh:mm:ss Avar date2 = '2018/05/14 05:04:22 AM';   // yyyy/mm/dd hh:mm:ss Avar date3 = '2018/05/04';   // yyyy/mm/ddvar date4 = '2018-05-04';   // yyyy-mm-ddvar date5 = '2018-05-14 15:04:22';   // yyyy-mm-dd HH:mm:ssvar date6 = '2018/05/14 14:04:22';   // yyyy/mm/dd HH:mm:ss
console.log(parseDateTime(date1))console.log(parseDateTime(date2))console.log(parseDateTime(date3))console.log(parseDateTime(date4))console.log(parseDateTime(date5))console.log(parseDateTime(date6))
**Output---**Mon May 14 2018 05:04:22 GMT+0530 (India Standard Time)Mon May 14 2018 05:04:22 GMT+0530 (India Standard Time)Fri May 04 2018 00:00:00 GMT+0530 (India Standard Time)Fri May 04 2018 00:00:00 GMT+0530 (India Standard Time)Mon May 14 2018 15:04:22 GMT+0530 (India Standard Time)Mon May 14 2018 14:04:22 GMT+0530 (India Standard Time)

您可以使用regex解析字符串以详细说明时间,然后创建日期或任何返回格式,例如:

//example : let dateString = "2018-08-17 01:02:03.4"
function strToDate(dateString){let reggie = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2}).(\d{1})/, [,year, month, day, hours, minutes, seconds, miliseconds] = reggie.exec(dateString), dateObject = new Date(year, month-1, day, hours, minutes, seconds, miliseconds);return dateObject;}alert(strToDate(dateString));

你可以试试这个:

function formatDate(userDOB) {const dob = new Date(userDOB);
const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July','August', 'September', 'October', 'November', 'December'];
const day = dob.getDate();const monthIndex = dob.getMonth();const year = dob.getFullYear();
// return day + ' ' + monthNames[monthIndex] + ' ' + year;return `${day} ${monthNames[monthIndex]} ${year}`;}
console.log(formatDate('1982-08-10'));

我写了一个可重用的函数,当我从服务器获取日期字符串时使用。
您可以传递所需的分隔符(/-etc…),分隔日、月和年,以便使用split()方法。
你可以在这个工作示例上看到并测试它。

<!DOCTYPE html><html><head><style></style></head><body><div><span>day:</span><span id='day'></span></div><div><span>month:</span><span id='month'></span></div><div><span>year:</span><span id='year'></span></div><br/><input type="button" id="" value="convert" onClick="convert('/','28/10/1980')"/><span>28/10/1980</span><script>function convert(delimiter,dateString){var splitted = dateString.split('/');// create a new date from the splitted stringvar myDate = new Date(splitted[2],splitted[1],splitted[0]);// now you can access the Date and use its methodsdocument.getElementById('day').innerHTML = myDate.getDate();document.getElementById('month').innerHTML = myDate.getMonth();document.getElementById('year').innerHTML = myDate.getFullYear();}</script></body></html>

另一种方法是在格式字符串上使用命名捕获组构建正则表达式,然后使用该正则表达式从日期字符串中提取日、月和年:

function parseDate(dateStr, format) {const regex = format.toLocaleLowerCase().replace(/\bd+\b/, '(?<day>\\d+)').replace(/\bm+\b/, '(?<month>\\d+)').replace(/\by+\b/, '(?<year>\\d+)')  
const parts = new RegExp(regex).exec(dateStr) || {};const { year, month, day } = parts.groups || {};return parts.length === 4 ? new Date(year, month-1, day) : undefined;}
const printDate = x => console.log(x ? x.toLocaleDateString() : x);
printDate(parseDate('05/11/1896', 'dd/mm/YYYY'));printDate(parseDate('07-12-2000', 'dd-mm-yy'));printDate(parseDate('07:12:2000', 'dd:mm:yy'));printDate(parseDate('2017/6/3', 'yy/MM/dd'));printDate(parseDate('2017-6-15', 'y-m-d'));printDate(parseDate('2015 6 25', 'y m d'));printDate(parseDate('2015625', 'y m d')); // bad format

这个答案基于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 yearif (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","-")

性能

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

结论

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

在此处输入图片描述

详情

我在Chrome81.0、Safari13.1、Firefox 75.0上对MacO High Sierra 10.13.6进行测试。解决方案parseDate(Ed)使用new Date(0)并手动设置UTC日期组件。

let ds = '2020-05-14T00:00Z'; // Valid ISO8601 UTC datelet 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;}
<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  

Chrome的搜索结果

在此处输入图片描述

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

只需将日期字符串(使用iso格式)与末尾的“T00:00:00”连接并使用JavaScript Date()构造函数,如下例所示。

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

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

在ISO格式中,如果您提供时间并且Z不存在于末尾string,日期将是本地时区而不是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());

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

因为如果您仅使用一个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))}}}

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

参考文献:

作为这里解释的插件,您可以使用new Date()创建日期并使用非常有用的toLocaleDateString()//日期类型函数对其进行格式化

举个例子:

console.log(new Date('1970-01-01').toLocaleDateString('es-ES')) // --> This will output '1/1/1970'

var parts ='2022-07-23'.split('-');console.log(parts[2]+"-"+parts[1]+"-"+parts[0]);

它是足够安全的方法,同时完全模块化(轻松修复dd/mm/yyyy到mm/dd/yyyy等)。适用于不同的分隔符,如“/”等。

上述产生:

23-07-2022