如何在JavaScript中输出ISO 8601格式的字符串?

我有一个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"
354971 次浏览

T后面少了一个+

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

应该这么做。

对于前导0,可以使用在这里:

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)

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

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

参见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

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

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

如果,以某种方式,你在一个浏览器上不支持它,我已经覆盖了你:

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

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

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

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

new Date().toJSON()

请注意:这个答案在2022-03年仍然得到好评。moment.js .js库是弃用。这是两个主要的替代方案:勒克桑Day.js,其他的在弃用链接中提到。

勒克桑

Luxon可以被认为是Moment的进化。作者是 艾萨克Cambron, Moment的长期贡献者。请阅读为什么 国际光子存在吗?和Luxon . properties中的Moment用户页 文档。< / p >

区域:提供国际时区:提供国际时区

Day.js

Day.js被设计成一个极简的Moment.js的替代品,使用 类似的API。它不是一个随意的替代品,但如果你习惯了 如果你正在使用Moment的API,想要快速上手,可以考虑使用 Day.js . < / p >

Locales:可单独导入的自定义数据文件时间 区域:Intl提供,通过插件

我使用Day.js是因为大小不同,但是Luxon更容易处理。


在web上,几乎每一个to- iso方法都会在输出字符串之前应用一个转换为“Z"ulu time (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#似乎喜欢它。

我通常不希望显示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;
}

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

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

假设后面的Z是需要的,否则就省略。

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代码高尔夫的一部分),我改进了它,使它可以在internetexplorer10或更早的版本上运行。虽然很丑,但能完成任务。

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

toISOString的问题是它只将datetime作为"Z"。

ISO-8601还定义了带小时和分钟时区差异的datetime,格式为2016-07-16T19:20:30+5:30(当时区在UTC之前时)和2016-07-16T19:20:30-01:00(当时区在UTC之后时)。

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

一旦有了以小时和分钟为单位的时区偏移量,就可以追加到datetime字符串。

我写了一篇关于它的博客: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);

我可以用非常少的代码得到以下的输出。

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

输出:

Fri Apr 02 2010 19:42 hrs

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

// 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

一个简短的例子:

console.log(new Date().toISOString().slice(0,19).replace('T', ' '))