如何在moment.js中将日期格式化为 ISO 8601?

309

你正在使用哪个版本的moment?文档中说常量是在2.7.0中添加的。 - joews
@joews 2.7.0。在问题中进行了澄清。看看我的答案,我弄明白了。文档不是非常清楚。 - sennett
是的,他们只在解析的上下文中提到特殊格式。很奇怪。 - joews
4
你可以尝试使用moment().toISOString() - Saahithyan Vigneswaran
9个回答

522
moment().toISOString(); // or format() - see below

http://momentjs.com/docs/#/displaying/as-iso-string/

更新 根据@sennet的答案和@dvlsg的评论(请查看Fiddle),应该指出formattoISOString之间存在差异。两者都是正确的,但底层处理方式不同。toISOString将其转换为Date对象,设置为UTC,然后使用本地日期原型函数在UTC中输出带毫秒的ISO8601字符串(Y年M月D日T时间S毫秒[Z])。另一方面,format使用默认格式(YYYY-MM-DDTHH:mm:ssZ),没有毫秒,并保留时区偏移量。

我已经提出了一个issue,因为我认为它可能会导致意外的结果。


2
我同意@Yashua的观点。我认为应该避免使用"format()",因为它不直观。此外,我认为没有必要存在一个仅包装本地"toISOString()"的函数。话虽如此,也许提供一个新的函数,例如:"toISO8601()",并且有选项保留时区和适当的文档说明会更好。 - Greivin López
8
如果您想获取UTC时间,但希望以自己的格式输出而不是ISO8601格式,可以使用以下代码:moment().utc().format("自定义格式") - StinkyCat
在Kibana中格式化日期很有用,但您无法访问JS时。 - bric3
7
如果想保持本地时区,请使用 moment().toISOString(true); - Benny Code

107

42
顺便提一下,尽管这两个答案都符合ISO格式要求,但它们并不相同。date.toISOString()会保留毫秒并使用协调世界时(UTC),而date.format()会舍弃毫秒并使用您本地的时区(或者至少在chrome浏览器中是这样的行为 -- http://jsfiddle.net/8gvhL1dz/22/)。 - dvlsg
使用.format()与阿拉伯语环境会导致出现阿拉伯符号而不是英文符号,这可能是不希望看到的。 - Matt Sgarlata
2
toISOString 不会输出本地时区的时间 - 它总是在(零偏移量)UTC。 - JoeTidee

26

也可以使用原始的JavaScript实现

new Date().toISOString() // "2017-08-26T16:31:02.349Z"

16
只有当你希望按照协调世界时(UTC)显示,而不保留时区信息时,才会这样做。 - JoeTidee
选择的日期正好是我的生日...哈哈 感谢您的回答... - FSRezende

18

当你使用 Mongoose 把日期存储到 MongoDB 中时,你需要使用 toISOString(),因为所有日期都以毫秒为单位存储为 ISOdates。

moment.format() 

2018-04-17T20:00:00Z

moment.toISOString() -> USE THIS TO STORE IN MONGOOSE

2018-04-17T20:00:00.000Z

12
var date = moment(new Date(), moment.ISO_8601);
console.log(date);

2
你能详细阐述一下你的回答吗? - Stephan Hogenboom

7
如果你需要格式化字符串:YYYY-MM-DDTHH:mm:ssZ
var date = moment();
console.log(date.format("YYYY-MM-DDTHH:mm:ssZ"));

5

如果你只需要日期部分(例如2017-06-27),并且希望它不受时区限制并且在阿拉伯语中也可以使用,这里是我写的代码:

function isoDate(date) {
    if (!date) {
        return null
    }
    date = moment(date).toDate()

    // don't call toISOString because it takes the time zone into
    // account which we don't want.  Also don't call .format() because it
    // returns Arabic instead of English

    var month = 1 + date.getMonth()
    if (month < 10) {
        month = '0' + month
    }
    var day = date.getDate()
    if (day < 10) {
        day = '0' + day
    }
    return date.getFullYear() + '-' + month + '-' + day
}

4

2020年的答案(包括时区支持)

我们遇到的问题是,默认情况下,ISO字符串不会根据您的时区进行本地化。因此,这有点糟糕,但以下是我们最终解决此问题的方法:

/** Imports Moment for time utilities. */
const moment = require("moment-timezone")
moment().tz("America/Chicago").format()

//** Returns now in ISO format in Central Time */
export function getNowISO() {
  return `${moment().toISOString(true).substring(0, 23)}Z`
}

这将为您留下一个精确的ISO格式化的、本地化的字符串。

重要提示: 现在Moment 建议在新项目中使用其他包。


2
var x = moment();

//date.format(moment.ISO_8601); // error

moment("2010-01-01T05:06:07", ["YYYY", moment.ISO_8601]);; // error
document.write(x);

3
虽然这段代码可以解决问题,但最好加入上下文来解释它是如何工作的。这有助于未来的用户学习,并将这些知识应用到他们自己的代码中。当代码被解释说明时,你还可能会得到用户的积极反馈,例如点赞。 - borchvm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接