306

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?

sennett
  • 8,014
  • 9
  • 46
  • 69

9 Answers9

520
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.

Community
  • 1
  • 1
cyberwombat
  • 38,105
  • 35
  • 175
  • 251
  • 2
    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. – Greivin López Apr 24 '17 at 01:47
  • 8
    If you want the utc time, but formatted your own way, instead of ISO8601, you can do the following: `moment().utc().format("OUTPUT_FORMAT")` – StinkyCat May 10 '17 at 14:35
  • Useful whn formating a date in kibana but you don't have access to JS. – bric3 Oct 06 '17 at 14:18
  • 6
    If you want to maintain the local timezone, use `moment().toISOString(true);`. – Benny Code Jul 23 '19 at 19:16
106

Use format with no parameters:

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

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

sennett
  • 8,014
  • 9
  • 46
  • 69
  • 42
    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 -- http://jsfiddle.net/8gvhL1dz/22/ ) – dvlsg Oct 16 '15 at 22:21
  • Using .format() with an Arabic locale leads to Arabic symbols rather than English ones, which is probably undesirable. – Matt Sgarlata Jun 27 '17 at 11:54
  • 2
    toISOString does not output in your local timezone - it is always in (zero offset) UTC. – JoeTidee Feb 25 '19 at 12:31
26

Also possible with vanilla JS

new Date().toISOString() // "2017-08-26T16:31:02.349Z"
artnikpro
  • 5,487
  • 4
  • 38
  • 40
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
webmaster
  • 1,960
  • 24
  • 29
11
var date = moment(new Date(), moment.ISO_8601);
console.log(date);
Jom
  • 138
  • 1
  • 5
6

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

var date = moment();
console.log(date.format("YYYY-MM-DDTHH:mm:ssZ"));
ZettaP
  • 719
  • 7
  • 11
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
}
Matt Sgarlata
  • 1,761
  • 1
  • 16
  • 13
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.

Davis Jones
  • 1,504
  • 3
  • 17
  • 25
2
var x = moment();

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

moment("2010-01-01T05:06:07", ["YYYY", moment.ISO_8601]);; // error
document.write(x);
4b0
  • 21,981
  • 30
  • 95
  • 142
Nishith
  • 107
  • 1
  • 9
  • 3
    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. – borchvm Mar 18 '20 at 06:41