将ISO日期字符串更改为日期对象 - JavaScript

时间:2014-11-19 09:11:23

标签: javascript date datetime

我陷入了一种奇怪的境地,不幸的是,即使做了一些RnD和谷歌搜索,我也无法解决这个问题。

我有一个ISO格式的日期字符串,如2014-11-03T19:38:34.203Z,我希望用new Date()方法将其转换为日期对象。

但是当我这样做时,输出是:

var isoDate = '2014-11-03T19:38:34.203Z';
console.log(new Date(isoDate)); //output is: Tue Nov 04 2014 01:08:34 GMT+0530 (IST)

我通过的日期为3 Nov,2014,输出为4 Nov,2014,因为我们当地时间(IST)的GMT +5.30。

那么,是否有任何通用方法可以使date对象返回Nov 3,2014的日期。

注意:我对时间戳没有任何问题。我们可以使用setHours()方法将时间字符串更改为零。我唯一需要的是date new Date()对象,其日期为3 Nov,2014

8 个答案:

答案 0 :(得分:13)

不要将字符串传递给Date构造函数,因此解析字符串非常糟糕。例如,IE 8根本不会解析ISO 8601格式字符串并返回 NaN 。编写自己的解析器非常简单:

function parseISOString(s) {
  var b = s.split(/\D+/);
  return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5], b[6]));
}

另请注意,如果时间为19:38:34.203 UTC且您的时区为UTC + 0530,则该时区的时间为次日01:08:34,因此日期不同。例如,对于澳大利亚东海岸但没有观察夏令时(即UTC +10)的人来说,它相当于:

4 November, 2014 05:38:34

修改

因此,如果您想将其返回到ISO日期,可以使用getISO*方法创建适合的格式,例如

function isoFormatDMY(d) {  
  function pad(n) {return (n<10? '0' :  '') + n}
  return pad(d.getUTCDate()) + '/' + pad(d.getUTCMonth() + 1) + '/' + d.getUTCFullYear();
}

var s = '2014-11-03T19:38:34.203Z';
var date = parseISOString(s);

console.log(isoFormatDMY(date)) // 03/11/2014

或使用ES5的toISOString

 parseISOString('2014-11-03T19:38:34.203Z').toISOString(); // 2014-11-03T19:38:34.203Z

适用于ES4前浏览器的简单polyfill:

if (!Date.prototype.toISOString) {

  Date.prototype.toISOString = function() {

    var d = this;

    // Padding functions 
    function pad(n) {return (n<10? '0' :  '') + n}
    function padd(n){return (n<100? '0' : '') + pad(n)}

    return d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()) +
           'T' + pad(d.getUTCHours()) + ':' + pad(d.getUTCMinutes()) + ':' + 
           pad(d.getUTCSeconds()) + '.' + padd(d.getMilliseconds()) + 'Z';
  }
}

答案 1 :(得分:5)

您可以使用&#34; getUTCDate()&#34;得到实际的日期。

var d = new Date('2014-11-03T19:38:34.203Z');
var n = d.getUTCDate();

但它只返回日期。获得月份&#34; getUTCMonth()&#34;并获得年份&#34; getUTCFullYear()&#34;。然后构建所有格式。例如

var n=[];
var d = new Date('2014-11-03T19:38:34.203Z');
var s = d.getUTCDate();
n.push(s);
s=d.getUTCMonth();
n.push(s);
s=d.getUTCFullYear();
n.push(s);

最后制作&#34; n&#34;作为一个对象。

一切顺利

答案 2 :(得分:3)

我也不关心时间戳/时区,因为我仅从SQL返回ISO格式的日期。为了避免在转换为Date对象时,一天向前或向后移动,

moment(ISOStringHere, 'YYYY-MM-DD HH:mm'); // leaving off Z makes it UTC to match database

这需要位于此处的Moment JS库:

https://momentjs.com/

答案 3 :(得分:1)

这取决于你以后想要对象做什么。您始终可以参考javascript的“UTC”日期函数。

检查参考: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

答案 4 :(得分:0)

出于显示目的,您可以简单地执行此操作... 给定ISO格式的“日期”,你可以实现,

<div> {{Date | date:"dd MMM yy hh:mm a" }} </div>

以所需格式显示(仅显示)日期的绝佳技巧。

希望它有所帮助!

答案 5 :(得分:0)

对于需要支持旧版本浏览器并针对日期字符串中的时区进行正确调整的用户而言,此功能很好用。我以RobG's answer为起点,但是不得不对其进行大量修改,因为它不适用于时区有偏移的字符串,例如“ -07:00”(即以“ Z”)。

// Parse an ISO date string (i.e. "2019-01-18T00:00:00.000Z",
// "2019-01-17T17:00:00.000-07:00", or "2019-01-18T07:00:00.000+07:00",
// which are the same time) and return a JavaScript Date object with the
// value represented by the string.
function isoStringToDate( isoString ) {

    // Split the string into an array based on the digit groups.
    var dateParts = isoString.split( /\D+/ );

    // Set up a date object with the current time.
    var returnDate = new Date();

    // Manually parse the parts of the string and set each part for the
    // date. Note: Using the UTC versions of these functions is necessary
    // because we're manually adjusting for time zones stored in the
    // string.
    returnDate.setUTCFullYear( parseInt( dateParts[ 0 ] ) );

    // The month numbers are one "off" from what normal humans would expect
    // because January == 0.
    returnDate.setUTCMonth( parseInt( dateParts[ 1 ] - 1 ) );
    returnDate.setUTCDate( parseInt( dateParts[ 2 ] ) );

    // Set the time parts of the date object.
    returnDate.setUTCHours( parseInt( dateParts[ 3 ] ) );
    returnDate.setUTCMinutes( parseInt( dateParts[ 4 ] ) );
    returnDate.setUTCSeconds( parseInt( dateParts[ 5 ] ) );
    returnDate.setUTCMilliseconds( parseInt( dateParts[ 6 ] ) );

    // Track the number of hours we need to adjust the date by based
    // on the timezone.
    var timezoneOffsetHours = 0;

    // If there's a value for either the hours or minutes offset.
    if ( dateParts[ 7 ] || dateParts[ 8 ] ) {

        // Track the number of minutes we need to adjust the date by
        // based on the timezone.
        var timezoneOffsetMinutes = 0;

        // If there's a value for the minutes offset.
        if ( dateParts[ 8 ] ) {

            // Convert the minutes value into an hours value.
            timezoneOffsetMinutes = parseInt( dateParts[ 8 ] ) / 60;
        }

        // Add the hours and minutes values to get the total offset in
        // hours.
        timezoneOffsetHours = parseInt( dateParts[ 7 ] ) + timezoneOffsetMinutes;

        // If the sign for the timezone is a plus to indicate the
        // timezone is ahead of UTC time.
        if ( isoString.substr( -6, 1 ) == "+" ) {

            // Make the offset negative since the hours will need to be
            // subtracted from the date.
            timezoneOffsetHours *= -1;
        }
    }

    // Get the current hours for the date and add the offset to get the
    // correct time adjusted for timezone.
    returnDate.setHours( returnDate.getHours() + timezoneOffsetHours );

    // Return the Date object calculated from the string.
    return returnDate;
}

用法/一些测试:

// All three of these tests output the same date (relative to your
// timezone) as they should, which in my case is:
// "Thu Jan 17 2019 17:00:00 GMT-0700 (Mountain Standard Time)".
console.log( isoStringToDate( "2019-01-18T00:00:00.000Z" ) );
console.log( isoStringToDate( "2019-01-17T17:00:00.000-07:00" ) );
console.log( isoStringToDate( "2019-01-18T07:00:00.000+07:00" ) );

答案 6 :(得分:0)

我从kevinmicke's的最佳答案开始,但是由于我需要代码生成器使用它,因此我担心代码的大小。最终,我最终得到了这个:

const parseDate = dateString => {
  const b = dateString.split(/\D+/);
  const offsetMult = dateString.indexOf('+') !== -1 ? -1 : 1;
  const hrOffset = offsetMult * (+b[7] || 0);
  const minOffset = offsetMult * (+b[8] || 0);  
  return new Date(Date.UTC(+b[0], +b[1] - 1, +b[2], +b[3] + hrOffset, +b[4] + minOffset, +b[5], +b[6] || 0));
};

答案 7 :(得分:0)

new Date(this.datePipe.transform(isoDate,'yyyy-MM-dd HH:mm:ss', 'UTC'));

Angular datepipe转换会将其转换为指定的简单日期时间格式,没有时区。如果是ISO字符串格式,则日期构造函数会将其视为UTC时间,但现在,日期构造函数会将其视为本地时间。

在我的情况下(IST)的示例:

input string: 2020-04-19T09:15:00.000Z
after transform this.datePipe.transform(input string)
2020-04-19 09:15:00
Date object 
new Date(this.datePipe.transform(isoDate,'yyyy-MM-dd HH:mm:ss', 'UTC'));//treats the transformed date as local timezone date when creating the date object
Sun Apr 19 2020 09:15:00 GMT+0530 (India Standard Time)