How do I format a date as ISO 8601 in moment.js?
Asked Answered
B

9

312

This docs mention moment.ISO_8601 as a formatting option (from 2.7.0 - http://momentjs.com/docs/#/parsing/special-formats/), but neither of these work (even 2.7.0):

var date = moment();
date.format(moment.ISO_8601); // error
moment.format(date, moment.ISO_8601); // error

(http://jsfiddle.net/b3d6uy05/1/)

How can I get an ISO 8601 from moment.js?

Bounden answered 8/9, 2014 at 13:7 Comment(4)
What version of moment are you using? The docs say that constant was added in 2.7.0.Agglutinate
@Agglutinate 2.7.0. Clarified in question. See my answer I figured it out. Docs not hugely clear though.Bounden
Yeah, they only mention special formats in the context of parsing. Odd.Agglutinate
u can try moment().toISOString()Banerjee
P
531
moment().toISOString(); // or format() - see below

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

Update Based on the answer: by @sennet and the comment by @dvlsg (see Fiddle) it should be noted that there is a difference between format and toISOString. Both are correct but the underlying process differs. toISOString converts to a Date object, sets to UTC then uses the native Date prototype function to output ISO8601 in UTC with milliseconds (YYYY-MM-DD[T]HH:mm:ss.SSS[Z]). On the other hand, format uses the default format (YYYY-MM-DDTHH:mm:ssZ) without milliseconds and maintains the timezone offset.

I've opened an issue as I think it can lead to unexpected results.

Pocked answered 21/2, 2015 at 3:49 Comment(4)
I agree with you @Yashua. I think the use of "format()" should be avoided because is not intuitive. Also I don't think a function that just wraps the native "toISOString()" should exist at all. That being said, perhaps giving a new function like: "toISO8601()" with the option to keep the timezone and a proper documentation will be better.Dawson
If you want the utc time, but formatted your own way, instead of ISO8601, you can do the following: moment().utc().format("OUTPUT_FORMAT")Ventilator
Useful whn formating a date in kibana but you don't have access to JS.Tegular
If you want to maintain the local timezone, use moment().toISOString(true);.Gober
B
108

Use format with no parameters:

var date = moment();
date.format(); // "2014-09-08T08:02:17-05:00"

(http://jsfiddle.net/8gvhL1dz/)

Bounden answered 8/9, 2014 at 13:7 Comment(3)
Just as a side note, these two answers are not the same, even though they both fulfill ISO format requirements. date.toISOString() will keep the milliseconds and use utc, date.format() will drop the milliseconds and use your local timezone (or at least, that's the behavior I am currently getting in chrome -- jsfiddle.net/8gvhL1dz/22 )Donate
Using .format() with an Arabic locale leads to Arabic symbols rather than English ones, which is probably undesirable.Howerton
toISOString does not output in your local timezone - it is always in (zero offset) UTC.Hermie
F
28

Also possible with vanilla JS

new Date().toISOString() // "2017-08-26T16:31:02.349Z"
Fiddlefaddle answered 26/8, 2017 at 16:31 Comment(1)
Only if you want it in UTC, without maintaining the timezone.Hermie
C
18

When you use Mongoose to store dates into MongoDB you need to use toISOString() because all dates are stored as ISOdates with miliseconds.

moment.format() 

2018-04-17T20:00:00Z

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

2018-04-17T20:00:00.000Z
Calliope answered 17/4, 2018 at 14:28 Comment(0)
A
12
var date = moment(new Date(), moment.ISO_8601);
console.log(date);
Anguished answered 19/11, 2020 at 5:11 Comment(1)
Can you elaborate your answer a bit?Broiler
M
7

If you need the formatting string : YYYY-MM-DDTHH:mm:ssZ

var date = moment();
console.log(date.format("YYYY-MM-DDTHH:mm:ssZ"));
Metsky answered 24/2, 2022 at 17:20 Comment(0)
H
5

If you just want the date portion (e.g. 2017-06-27), and you want it to work regardless of time zone and also in Arabic, here is code I wrote:

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
}
Howerton answered 27/6, 2017 at 12:4 Comment(0)
E
4

Answer in 2020 (Includes Timezone Support)

The problem we were having is that, by default, ISOStrings aren't localized to your timezone. So, this is kinda hacky, but here's how we ended up solving this issue:

/** 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`
}

This will leave you with an exact ISO-formatted, localized string.

Important note: Moment now suggests using other packages for new projects.

Euhemerism answered 4/11, 2020 at 19:29 Comment(0)
C
2
var x = moment();

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

moment("2010-01-01T05:06:07", ["YYYY", moment.ISO_8601]);; // error
document.write(x);
Copestone answered 18/3, 2020 at 6:20 Comment(1)
While this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn, and apply that knowledge to their own code. You are also likely to have positive feedback from users in the form of upvotes, when the code is explained.Ionone

© 2022 - 2024 — McMap. All rights reserved.