【问题标题】:How do I output an ISO 8601 formatted string in JavaScript?如何在 JavaScript 中输出 ISO 8601 格式的字符串?
【发布时间】:2011-02-04 03:16:05
【问题描述】:

我有一个Date 对象。 如何渲染以下 sn-p 的 title 部分?

<abbr title="2010-04-02T14:12:07">A couple days ago</abbr>

我有来自另一个库的“相对时间”部分。

我尝试了以下方法:

function isoDate(msSinceEpoch) {

   var d = new Date(msSinceEpoch);
   return d.getUTCFullYear() + '-' + (d.getUTCMonth() + 1) + '-' + d.getUTCDate() + 'T' +
          d.getUTCHours() + ':' + d.getUTCMinutes() + ':' + d.getUTCSeconds();

}

但这给了我:

"2010-4-2T3:19"

【问题讨论】:

    标签: javascript datetime iso8601


    【解决方案1】:

    在“T”之后缺少一个“+”

    isoDate: function(msSinceEpoch) {
      var d = new Date(msSinceEpoch);
      return d.getUTCFullYear() + '-' + (d.getUTCMonth() + 1) + '-' + d.getUTCDate() + 'T'
             + d.getUTCHours() + ':' + d.getUTCMinutes() + ':' + d.getUTCSeconds();
    }
    

    应该这样做。

    对于前导零,您可以从 here 使用它:

    function PadDigits(n, totalDigits) 
    { 
        n = n.toString(); 
        var pd = ''; 
        if (totalDigits > n.length) 
        { 
            for (i=0; i < (totalDigits-n.length); i++) 
            { 
                pd += '0'; 
            } 
        } 
        return pd + n.toString(); 
    } 
    

    像这样使用它:

    PadDigits(d.getUTCHours(),2)
    

    【讨论】:

    • 伟大的收获!但是,它并没有解决缺失的“0”。
    • 编写一个函数将整数转换为 2 个字符的字符串(如果参数小于 10,则在前面加上 '0'),并为日期/时间的每个部分调用它。跨度>
    【解决方案2】:

    我会用这个小扩展来Date - http://blog.stevenlevithan.com/archives/date-time-format

    var date = new Date(msSinceEpoch);
    date.format("isoDateTime"); // 2007-06-09T17:46:21
    

    【讨论】:

      【解决方案3】:

      参见https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference:Global_Objects:Date页面上的最后一个示例:

      /* Use a function for the exact format desired... */
      function ISODateString(d) {
          function pad(n) {return n<10 ? '0'+n : n}
          return d.getUTCFullYear()+'-'
               + pad(d.getUTCMonth()+1)+'-'
               + pad(d.getUTCDate())+'T'
               + pad(d.getUTCHours())+':'
               + pad(d.getUTCMinutes())+':'
               + pad(d.getUTCSeconds())+'Z'
      }
      
      var d = new Date();
      console.log(ISODateString(d)); // Prints something like 2009-09-28T19:03:12Z
      

      【讨论】:

      • OP (&lt;abbr title="2010-04-02T14:12:07"&gt;) 提供的样本没有时区。也许他们想要本地时间,这对 UI 时间字符串有意义?
      【解决方案4】:

      已经有一个名为toISOString()的函数:

      var date = new Date();
      date.toISOString(); //"2011-12-19T15:28:46.493Z"
      

      如果不知何故,您使用的 a browser 不支持它,我已经为您提供保障:

      if (!Date.prototype.toISOString) {
        (function() {
      
          function pad(number) {
            var r = String(number);
            if (r.length === 1) {
              r = '0' + r;
            }
            return r;
          }
      
          Date.prototype.toISOString = function() {
            return this.getUTCFullYear() +
              '-' + pad(this.getUTCMonth() + 1) +
              '-' + pad(this.getUTCDate()) +
              'T' + pad(this.getUTCHours()) +
              ':' + pad(this.getUTCMinutes()) +
              ':' + pad(this.getUTCSeconds()) +
              '.' + String((this.getUTCMilliseconds() / 1000).toFixed(3)).slice(2, 5) +
              'Z';
          };
      
        }());
      }
      
      console.log(new Date().toISOString())

      【讨论】:

      • .toISOString() 肯定会返回 UTC 日期?
      • new Date("xx").toISOString() 产生 NaN-NaN-NaNTNaN:NaN:NaN.NZ 原生实现抛出 RangeException。
      • 如果你想将一个日期对象传递给一个soap服务......就是这样! :) 谢谢。
      • 在OP提供的示例中,没有毫秒或时区。
      • 所有像“getUTCFullYear”这样的函数调用都失败了,因为 IE 文档模式 5 不知道它们。
      【解决方案5】:

      如果你不需要支持 IE7,下面是一个很棒的简洁的 hack:

      console.log(
        JSON.parse(JSON.stringify(new Date()))
      )

      【讨论】:

      • 对于 IE7,如果包含 json3-library (bestiejs.github.io/json3),这个决定也很合适。谢谢:)
      • 在 IE8 中也失败了。 ("'JSON' 未定义")
      • 通过 JSON 往返是丑陋的,特别是如果您的既定目标是简洁;请改用日期的toJSON 方法。 JSON.stringify 无论如何都在暗中使用它。
      • @CeesTimmerman IE8 支持JSON 对象,但在某些兼容模式下不支持。见stackoverflow.com/questions/4715373/…
      • 这在什么方面比.toISOString() 更好?
      【解决方案6】:

      最短,但 Internet Explorer 8 及更早版本不支持:

      new Date().toJSON()
      

      【讨论】:

        【解决方案7】:

        Web 上几乎所有的 to-ISO 方法都通过在输出字符串之前应用转换为“Z”ulu 时间 (UTC) 来删除时区信息。浏览器的原生 .toISOString() 也会丢弃时区信息。

        这会丢弃有价值的信息,因为服务器或接收者始终可以将完整的 ISO 日期转换为 Zulu 时间或它需要的任何时区,同时仍能获取发送者的时区信息。

        我遇到的最佳解决方案是使用 Moment.js javascript 库并使用以下代码:

        获取带有时区信息和毫秒的当前 ISO 时间

        now = moment().format("YYYY-MM-DDTHH:mm:ss.SSSZZ")
        // "2013-03-08T20:11:11.234+0100"
        
        now = moment().utc().format("YYYY-MM-DDTHH:mm:ss.SSSZZ")
        // "2013-03-08T19:11:11.234+0000"
        
        now = moment().utc().format("YYYY-MM-DDTHH:mm:ss") + "Z"
        // "2013-03-08T19:11:11Z" <- better use the native .toISOString() 
        

        获取包含时区信息但不包含毫秒的原生 JavaScript Date 对象的 ISO 时间

        var current_time = Date.now();
        moment(current_time).format("YYYY-MM-DDTHH:mm:ssZZ")
        

        这可以与 Date.js 结合得到像 Date.today() 这样的函数,然后可以将其结果传递给 moment。

        像这样格式化的日期字符串是 JSON 兼容的,并且很适合存储到数据库中。 Python 和 C# 似乎很喜欢它。

        【讨论】:

        • 不要和约会的人混在一起。只需使用 moment.js 并保存你的头发。
        • 实际上,在 python 和 db 上,它被证明是一种痛苦。 db 使用 UTC(没有问题,因为您可以轻松地转换为 UTC 服务器端),因此如果您想保留偏移量信息,您需要另一个字段。并且 Python 更喜欢使用纳秒而不是 javascript 的毫秒,这通常足够并且比普通秒更可取。在 python 上,只有 dateutil.parser.parse 可以正确解析它,并且编写毫秒 ISO 需要一个 "_when = when.strftime("%Y-%m-%dT%H:%M: %S.%f%z"); return _when[:-8] + _when[-5:]" 将 nanos 转换为 millis。这不好。
        • 您实际上可以像这样省略格式:moment(new Date()).format()。 “从 1.5.0 版开始,在没有格式的情况下调用 moment#format 将默认为 ... ISO8601 格式 YYYY-MM-DDTHH:mm:ssZ”。文档:从momentjs.com/docs/#/displaying/fromnow向上滚动
        • 好点@user193130,但您确实需要小心,因为输出与本机方法不同。 moment().format()"2015-03-04T17:16:05+03:00"(new Date()).toISOString()"2015-03-04T14:16:24.555Z"
        • 可能很挑剔,但这些示例返回的是与 UTC 的当前偏移量,而不是时区。时区是一个地理区域,通常表示为例如“美国/多伦多”。许多时区每年两次更改其 UTC 偏移量,并且不能(总是)从当前的 UTC 偏移量确定时区......因此这个答案也删除了时区信息:-)
        【解决方案8】:

        我通常不想显示 UTC 日期,因为客户不喜欢在脑海中进行转换。为了显示 本地 ISO 日期,我使用以下函数:

        function toLocalIsoString(date, includeSeconds) {
            function pad(n) { return n < 10 ? '0' + n : n }
            var localIsoString = date.getFullYear() + '-'
                + pad(date.getMonth() + 1) + '-'
                + pad(date.getDate()) + 'T'
                + pad(date.getHours()) + ':'
                + pad(date.getMinutes()) + ':'
                + pad(date.getSeconds());
            if(date.getTimezoneOffset() == 0) localIsoString += 'Z';
            return localIsoString;
        };
        

        上面的函数省略了时区偏移信息(除非本地时间恰好是UTC),所以我使用下面的函数来显示单个位置的本地偏移。如果您希望每次都显示偏移量,还可以将其输出附加到上述函数的结果中:

        function getOffsetFromUTC() {
            var offset = new Date().getTimezoneOffset();
            return ((offset < 0 ? '+' : '-')
                + pad(Math.abs(offset / 60), 2)
                + ':'
                + pad(Math.abs(offset % 60), 2))
        };
        

        toLocalIsoString 使用pad。如果需要,它几乎可以像任何 pad 功能一样工作,但为了完整起见,这是我使用的:

        // Pad a number to length using padChar
        function pad(number, length, padChar) {
            if (typeof length === 'undefined') length = 2;
            if (typeof padChar === 'undefined') padChar = '0';
            var str = "" + number;
            while (str.length < length) {
                str = padChar + str;
            }
            return str;
        }
        

        【讨论】:

          【解决方案9】:

          提出的问题是 ISO 格式 降低了精度。瞧:

           new Date().toISOString().slice(0, 19) + 'Z'
           // '2014-10-23T13:18:06Z'
          

          假设需要尾随 Z,否则就省略。

          【讨论】:

            【解决方案10】:
            function getdatetime() {
                d = new Date();
                return (1e3-~d.getUTCMonth()*10+d.toUTCString()+1e3+d/1)
                    .replace(/1(..)..*?(\d+)\D+(\d+).(\S+).*(...)/,'$3-$1-$2T$4.$5Z')
                    .replace(/-(\d)T/,'-0$1T');
            }
            

            我在某处找到了有关 StackOverflow 的基础知识(我相信它是其他一些 Stack Exchange 代码打高尔夫球的一部分),我对其进行了改进,使其也适用于 Internet Explorer 10 或更早版本。它很丑,但它可以完成工作。

            【讨论】:

              【解决方案11】:
              function timeStr(d) { 
                return ''+
                  d.getFullYear()+
                  ('0'+(d.getMonth()+1)).slice(-2)+
                  ('0'+d.getDate()).slice(-2)+
                  ('0'+d.getHours()).slice(-2)+
                  ('0'+d.getMinutes()).slice(-2)+
                  ('0'+d.getSeconds()).slice(-2);
              }
              

              【讨论】:

              • 在 IE5 模式下,我不得不走这条路,因为这里的所有其他答案都使用了不存在的功能。
              【解决方案12】:

              toISOString 的问题在于它只给出日期时间为“Z”。

              ISO-8601 还定义了带有时区差异的日期时间,以小时和分钟为单位,格式为 2016-07-16T19:20:30+5:30(当时区早于 UTC 时)和 2016-07-16T19:20: 30-01:00(时区晚于 UTC 时)。

              我不认为使用另一个插件,moment.js 来完成这么小的任务不是一个好主意,尤其是当你用几行代码就可以得到它的时候。

              一旦您有了小时和分钟的时区偏移量,您就可以附加到日期时间字符串。

              我在上面写了一篇博文:http://usefulangle.com/post/30/javascript-get-date-time-with-offset-hours-minutes

              var timezone_offset_min = new Date().getTimezoneOffset(),
                offset_hrs = parseInt(Math.abs(timezone_offset_min / 60)),
                offset_min = Math.abs(timezone_offset_min % 60),
                timezone_standard;
              
              if (offset_hrs < 10)
                offset_hrs = '0' + offset_hrs;
              
              if (offset_min > 10)
                offset_min = '0' + offset_min;
              
              // getTimezoneOffset returns an offset which is positive if the local timezone is behind UTC and vice-versa.
              // So add an opposite sign to the offset
              // If offset is 0, it means timezone is UTC
              if (timezone_offset_min < 0)
                timezone_standard = '+' + offset_hrs + ':' + offset_min;
              else if (timezone_offset_min > 0)
                timezone_standard = '-' + offset_hrs + ':' + offset_min;
              else if (timezone_offset_min == 0)
                timezone_standard = 'Z';
              
              // Timezone difference in hours and minutes
              // String such as +5:30 or -6:00 or Z
              console.log(timezone_standard);

              【讨论】:

              • 错字:if (offset_min > 10) 应该是 <..>
              • 最同意你的帖子 - 话虽如此,'Z' 暗示有目的的“zulu”转换,而 00:00 暗示它就是这样(本地在 GMT 区域的某个地方)。如果这是一个函数,我会传递一个“convertToZulu”参数来转换日期并附加 z;否则没有转换和 00:00 而不是 Z。
              【解决方案13】:

              我能够用非常少的代码得到低于输出。

              var ps = new Date('2010-04-02T14:12:07')  ;
              ps = ps.toDateString() + " " + ps.getHours() + ":"+ ps.getMinutes() + " hrs";
              

              输出:

              Fri Apr 02 2010 19:42 hrs
              

              【讨论】:

                【解决方案14】:

                用一些糖和现代语法来扩展肖恩的伟大而简洁的答案:

                // date.js
                
                const getMonthName = (num) => {
                  const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Oct', 'Nov', 'Dec'];
                  return months[num];
                };
                
                const formatDate = (d) => {
                  const date = new Date(d);
                  const year = date.getFullYear();
                  const month = getMonthName(date.getMonth());
                  const day = ('0' + date.getDate()).slice(-2);
                  const hour = ('0' + date.getHours()).slice(-2);
                  const minutes = ('0' + date.getMinutes()).slice(-2);
                
                  return `${year} ${month} ${day}, ${hour}:${minutes}`;
                };
                
                module.exports = formatDate;
                

                然后例如。

                import formatDate = require('./date');
                
                const myDate = "2018-07-24T13:44:46.493Z"; // Actual value from wherever, eg. MongoDB date
                console.log(formatDate(myDate)); // 2018 Jul 24, 13:44
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-11-22
                  • 2015-11-16
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多