Как вывести строку в формате ISO 8601 в JavaScript?

У меня есть Date объект. Как визуализировать 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"

person James A. Rosen    schedule 04.04.2010    source источник


Ответы (14)


Уже существует функция под названием toISOString() :

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

Если каким-то образом вы оказались на a браузер, который его не поддерживает, я вам помогу:

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

person Anatoly Mironov    schedule 19.12.2011
comment
.toISOString () определенно возвращает дату в формате UTC? - person Jon Wells; 12.12.2012
comment
new Date("xx").toISOString() производит NaN-NaN-NaNTNaN:NaN:NaN.NZ Собственная реализация выдает исключение RangeException. - person Joseph Lennox; 19.08.2014
comment
Если вы хотите передать объект даты в мыльную службу ... вот способ! :) Спасибо. - person thinklinux; 03.12.2014
comment
В образце, предоставленном OP, нет миллисекунд или часового пояса. - person Dan Dascalescu; 14.09.2016
comment
Все эти вызовы функций, такие как getUTCFullYear, не работают, потому что они не известны режиму документа IE 5. - person Elaskanator; 05.03.2018
comment
@JosephLennox Это время в Готэм-сити? - person Dai; 07.02.2020

См. Последний пример на странице 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
person Community    schedule 05.04.2010
comment
Образец, предоставленный OP (<abbr title="2010-04-02T14:12:07">), не имеет часового пояса. Возможно, им нужно местное время, которое имело бы смысл для строки времени пользовательского интерфейса? - person Dan Dascalescu; 14.09.2016

Почти каждый метод преобразования в ISO в Интернете удаляет информацию о часовом поясе, применяя преобразование ко времени ulu «Z» (UTC) перед выводом строки. Собственная функция браузера .toISOString () также удаляет информацию о часовом поясе.

Это отбрасывает ценную информацию, поскольку сервер или получатель всегда может преобразовать полную дату ISO во время Zulu или в любой другой часовой пояс, который ему требуется, при этом получая информацию о часовом поясе отправителя.

Лучшее решение, с которым я столкнулся, - использовать JavaScript Moment.js. библиотеку и используйте следующий код:

Чтобы получить текущее время 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() 

Чтобы получить время ISO для собственного объекта JavaScript Date с информацией о часовом поясе, но без миллисекунд

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

Это можно комбинировать с Date.js, чтобы получить такие функции, как Date.today (), результат которых затем можно передать моменту.

Строка даты, отформатированная таким образом, является компилятором JSON и хорошо поддается хранению в базе данных. Кажется, это нравится Python и C #.

person Daniel F    schedule 08.03.2013
comment
не балуйтесь людьми свиданий. Просто используйте moment.js и сохраните волосы. - person Valamas; 15.03.2013
comment
на самом деле, на 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:] для преобразования нанометров в миллисекунды. это не хорошо. - person Daniel F; 04.06.2013
comment
Фактически вы можете просто опустить такой формат: moment(new Date()).format(). Начиная с версии 1.5.0, формат # вызывающего момента без формата по умолчанию будет ... форматом ISO8601 YYYY-MM-DDTHH:mm:ssZ. Документ: прокрутите вверх от momentjs.com/docs/#/displaying/fromnow. - person user193130; 20.02.2014
comment
Хороший момент @ user193130, но вам действительно нужно быть осторожным, потому что вывод отличается от собственного метода. moment().format() "2015-03-04T17:16:05+03:00" (new Date()).toISOString() "2015-03-04T14:16:24.555Z" - person Olga; 04.03.2015
comment
Может быть, это придирчиво, но эти примеры возвращают текущее смещение от UTC, а не часовой пояс. Часовой пояс - это географический регион, обычно выражаемый как, например, Америка / Торонто. Многие часовые пояса меняют свое смещение UTC дважды в год, и часовой пояс не может (всегда) быть определен по текущему смещению UTC ... таким образом, этот ответ также удаляет информацию о часовом поясе :-) - person Martin Fido; 02.08.2016
comment
Эти примеры предназначены для иллюстрации того, как выводить ISO 8601, который, кроме возможности хранить смещение UTC, не служит другой цели, кроме как содержать информацию о времени. Если вам нужно преобразовать часовой пояс, вы можете взглянуть на momentjs.com/timezone. - person Daniel F; 03.08.2016
comment
Moment - это довольно большой плагин, который нужно включить с минимизированным размером 50 КБ, чтобы просто иметь некоторую простую обработку даты, которую вы могли бы сделать с помощью пары строк. - person Juha Untinen; 24.07.2018
comment
@JuhaUntinen Верно, но если вы используете CDN, возможно, он уже кэширован в браузере. Минимизированный без локали - 16,4 КБ (= только английские строки), с языками 66,4 КБ. - person Daniel F; 24.07.2018

Был задан вопрос о формате ISO с пониженной точностью. Вуаля:

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

Предполагая, что конечный Z нужен, в противном случае просто опустите.

person arcseldon    schedule 23.10.2014

Самый короткий, но не поддерживается Internet Explorer 8 и более ранними версиями:

new Date().toJSON()
person younes0    schedule 08.11.2012

Если вам не нужна поддержка IE7, вот отличный и краткий совет:

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

person Russell Davis    schedule 03.05.2012
comment
для IE7 это решение тоже подходит, если была включена json3-библиотека (bestiejs.github.io/json3) . Спасибо :) - person vladimir; 02.10.2013
comment
Также не работает в IE8. ('JSON' не определен) - person Cees Timmerman; 03.10.2013
comment
Обращение через JSON некрасиво, особенно если ваша заявленная цель - краткость; вместо этого используйте метод toJSON даты. JSON.stringify все равно использует его под прикрытием. - person Mark Amery; 02.03.2015
comment
@CeesTimmerman IE8 поддерживает объект JSON, но не в некоторых режимах совместимости. См. stackoverflow.com / questions / 4715373 / - person Mark Amery; 02.03.2015
comment
Чем это лучше, чем .toISOString()? - person Martin; 23.03.2019

Обычно я не хочу отображать дату в формате 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 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;
}
person Charles Burns    schedule 23.04.2013

Проблема с toISOString заключается в том, что он предоставляет datetime только как 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);

person Useful Angle    schedule 05.01.2017

После буквы T отсутствует знак "+"

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

должен это сделать.

Для начальных нулей вы можете использовать это из здесь:

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)
person kaiz.net    schedule 04.04.2010
comment
Отличный улов! Однако он не адресует недостающие нули. - person James A. Rosen; 04.04.2010
comment
Напишите функцию для преобразования целого числа в двухсимвольную строку (с добавлением «0», если аргумент меньше 10) и вызовите ее для каждой части даты / времени. - person dan04; 04.04.2010

Я смог получить результат ниже с очень меньшим количеством кода.

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

Выход:

Fri Apr 02 2010 19:42 hrs
person Srikanth Srikanth    schedule 26.02.2017

Я бы просто использовал это небольшое расширение для Date - http://blog.stevenlevithan.com/archives/date-time-format

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

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

Я где-то нашел основы Stack Overflow (я считаю, что это было частью какой-то другой игры в коде Stack Exchange), и я улучшил его, чтобы он работал и в Internet Explorer 10 или более ранней версии. Это уродливо, но свою работу выполняет.

person Jonas Byström    schedule 05.03.2015

Чтобы расширить отличный и лаконичный ответ Шона, добавив немного сахара и современного синтаксиса:

// 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
person Juha Untinen    schedule 24.07.2018

person    schedule
comment
В режиме IE5 мне пришлось пойти по этому пути, поскольку все остальные ответы здесь использовали функции, которых не существует. - person Elaskanator; 05.03.2018