Date.prototype.toISOString()
Formats a date as a 24-character ISO 8601 string in UTC, always ending in Z.
toISOString()- Added in JavaScript ES5 (2009)
Return value
stringA string in the date time string format according to universal time. It is always 24 characters (YYYY-MM-DDTHH:mm:ss.sssZ) or, for years outside 0000–9999, 27 characters (±YYYYYY-MM-DDTHH:mm:ss.sssZ). The time zone is always UTC, denoted by the trailing Z.
Errors
Throws a RangeError if the date is invalid, or if its year cannot be represented in the date time string format.
Changelog
- PHP ES5 (2009)Years outside 0000–9999 are rendered in the expanded ±YYYYYY form, making the string 27 characters instead of 24.
toISOString() is the format to reach for whenever a date leaves your program — an API body, a log line, a database column, a filename. It is fixed-width, sorts correctly as plain text, and carries no locale or host time zone, so the same instant produces the same string on every machine.
It is always UTC
The method ignores the host time zone entirely. A Date built from local components will still print in UTC, so the date portion can differ from the calendar day the user sees:
// host in UTC+10
new Date(2024, 0, 15, 9, 30).toISOString();
// "2024-01-14T23:30:00.000Z" — the 14th, not the 15thThat is correct behaviour, not a bug. If you need the local calendar day, build the string from getFullYear(), getMonth() and getDate(), or use toLocaleDateString() with sv-SE and an explicit timeZone.
Invalid dates throw
Unlike toString(), which returns the string "Invalid Date", this method raises a RangeError. Guard with Number.isNaN(date.valueOf()) before formatting anything you did not construct yourself.
Milliseconds are never omitted
The .sss segment is always present, even when it is .000. Some parsers and some other languages emit it only when non-zero, so string comparisons across systems can fail on that alone.
Example
When to use it
- Serializing a timestamp into a JSON request body or a log line
- Producing a sortable date key for a filename or database column
- Normalizing user-entered dates to a single canonical UTC representation
Frequently asked questions
Why does toISOString give me the wrong day?
Because it always prints UTC, and your local date is being shifted by the time zone offset. A date at 9:30 local time in UTC+10 is 23:30 the previous day in UTC. Use toLocaleDateString() with an explicit timeZone if you need the local calendar day.
How do I get an ISO string in local time instead of UTC?
There is no built-in for it — assemble the string yourself from getFullYear(), getMonth() + 1, getDate(), getHours(), getMinutes() and getSeconds(), padding each to two digits, or use Intl.DateTimeFormat with the sv-SE locale, which formats close to ISO order.
What is the difference between toISOString and toJSON?
For a valid date they return exactly the same string; toJSON() returns null for an invalid date while toISOString() throws a RangeError. toJSON() is the one JSON.stringify calls automatically.
More examples
Safe formatting for unknown input
Checking valueOf() for NaN turns the RangeError into a null return, so one bad row in a data set does not abort the whole loop.
function toIso(value) {
const d = new Date(value);
return Number.isNaN(d.valueOf()) ? null : d.toISOString();
}
console.log(toIso("2024-06-01T12:00:00Z"));
console.log(toIso(1717243200000));
console.log(toIso("tomorrow"));ISO strings sort as text
Because every field is zero-padded and ordered largest-unit-first, a plain lexicographic sort of ISO strings matches chronological order — useful for sorting keys you never parse back into dates.
const stamps = [
new Date(Date.UTC(2024, 2, 1)),
new Date(Date.UTC(2023, 11, 31)),
new Date(Date.UTC(2024, 0, 15)),
].map((d) => d.toISOString());
console.log([...stamps].sort());Date-only slice for an API query
The fixed width means slicing is safe: characters 0–10 are always YYYY-MM-DD and 0–19 always reach the end of the seconds field, so you can drop the milliseconds for APIs that reject them.
const d = new Date(Date.UTC(2024, 4, 9, 23, 15));
console.log(d.toISOString().slice(0, 10));
console.log(d.toISOString().slice(0, 19) + "Z");
Discussion