How do I output an ISO 8601 formatted string in JavaScript?
我有一个
1 | A couple days ago</abbr> |
我有另一个图书馆的"相对语言时间"部分。
我尝试了以下方法:
1 2 3 4 5 6 7 | function isoDate(msSinceEpoch) { var d = new Date(msSinceEpoch); return d.getUTCFullYear() + '-' + (d.getUTCMonth() + 1) + '-' + d.getUTCDate() + 'T' + d.getUTCHours() + ':' + d.getUTCMinutes() + ':' + d.getUTCSeconds(); } |
但这给了我:
1 | "2010-4-2T3:19" |
已经有一个名为
1 2 | var date = new Date(); date.toISOString(); //"2011-12-19T15:28:46.493Z" |
如果以某种方式您在不支持它的浏览器上,那么我可以满足您的要求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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'; }; }() ); } |
请参阅第https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference:Global_Objects:Date上的最后一个示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* 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 |
网络上几乎所有的to-ISO方法都通过在输出字符串之前对" Z" ulu time(UTC)进行转换来删除时区信息。浏览器的本机.toISOString()也会删除时区信息。
这会丢弃有价值的信息,因为服务器或收件人可以始终将完整的ISO日期转换为Zulu时间或所需的任何时区,同时仍能获取发送者的时区信息。
我遇到的最好的解决方案是使用Moment.js javascript库并使用以下代码:
获取带有时区信息和毫秒的当前ISO时间
1 2 3 4 5 6 7 8 | 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时间
1 2 | var current_time = Date.now(); moment(current_time).format("YYYY-MM-DDTHH:mm:ssZZ") |
可以将它与Date.js结合使用,以获取类似Date.today()的函数,然后将其结果传递给一下。
像这样格式化的日期字符串是JSON兼容的,很适合存储在数据库中。 Python和C#似乎很喜欢。
提出的问题是精度降低的ISO格式。瞧:
1 2 | new Date().toISOString().slice(0, 19) + 'Z' // '2014-10-23T13:18:06Z' |
假设需要尾随的Z,否则可以忽略。
最短,但InternetExplorer8和更早版本不支持:
1 | new Date().toJSON() |
如果您不需要支持IE7,则以下是一个简洁的好方法:
1 | JSON.parse(JSON.stringify(new Date())) |
我通常不希望显示UTC日期,因为客户不喜欢在头上进行转换。要显示本地ISO日期,请使用以下功能:
1 2 3 4 5 6 7 8 9 10 11 | 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),所以我使用下面的函数在单个位置显示本地偏移。如果希望每次都显示偏移量,还可以将其输出附加到上述函数的结果中:
1 2 3 4 5 6 7 | function getOffsetFromUTC() { var offset = new Date().getTimezoneOffset(); return ((offset < 0 ? '+' : '-') + pad(Math.abs(offset / 60), 2) + ':' + pad(Math.abs(offset % 60), 2)) }; |
1 2 3 4 5 6 7 8 9 10 | // 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; } |
toISOString的问题在于,它仅将日期时间设置为" Z"。
ISO-8601还使用带有时区差异的小时和分钟来定义日期时间,格式为2016-07-16T19:20:30 + 5:30(时区在UTC之前)和2016-07-16T19:20:30-01 :00(时区在UTC后面)。
我不认为将另一个插件moment.js用于如此小的任务不是一个好主意,尤其是当您可以使用几行代码来获得它时。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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); |
一旦时区偏移了小时和分钟,就可以追加到datetime字符串。
我在上面写了一篇博客文章:http://usefulangle.com/post/30/javascript-get-date-time-with-offset-hours-minutes
1 2 3 4 5 6 7 8 9 | 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); } |
在" T"之后缺少" +"
1 2 3 4 5 | isoDate: function(msSinceEpoch) { var d = new Date(msSinceEpoch); return d.getUTCFullYear() + '-' + (d.getUTCMonth() + 1) + '-' + d.getUTCDate() + 'T' + d.getUTCHours() + ':' + d.getUTCMinutes() + ':' + d.getUTCSeconds(); } |
应该这样做。
对于前导零,您可以从此处使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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(); } |
像这样使用它:
1 | PadDigits(d.getUTCHours(),2) |
我能够用更少的代码获得下面的输出。
1 2 | var ps = new Date('2010-04-02T14:12:07') ; ps = ps.toDateString() +"" + ps.getHours() +":"+ ps.getMinutes() +" hrs"; |
输出:
1 | Fri Apr 02 2010 19:42 hrs |
我只想使用
1 2 | var date = new Date(msSinceEpoch); date.format("isoDateTime"); // 2007-06-09T17:46:21 |
用一些糖和现代语法扩展Sean的简洁明了的答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // 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; |
然后例如。
1 2 3 4 | 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 |
1 2 3 4 5 6 | 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的基础知识(我相信它是其他StackExchange代码打高尔夫的一部分),并且对其进行了改进,因此它也可以在InternetExplorer10或更早版本上使用。很难看,但是可以完成工作。