Date.prototype.toString, toUTCString, toDateString and toTimeString
Four formats predating Intl, in English regardless of locale. toUTCString still matters — it is the format HTTP dates use — and the rest are mostly what you see when a Date lands in a template literal by accident.
Demo
toUTCString produces the RFC 7231 format that HTTP headers use — always GMT, always English day and month abbreviations, always the same shape. The demo uses it rather than toString because toString embeds the reader local timezone name and would differ for everyone. The last case is worth contrasting with toISOString: an invalid Date formats as the string 'Invalid Date' here, where toISOString throws a RangeError.
Common patterns
res.setHeader('Last-Modified', d.toUTCString());
console.log(`${d}`); // calls toString
d.toLocaleDateString('en-GB', {dateStyle: 'long'});
Examples
Pitfalls
new Date('2026-03-15T12:00:00Z').toDateString()
new Date('2026-03-15T12:00:00Z').toLocaleDateString('de-DE')
new Date(0).toString()
new Date(0).toISOString()
`Due: ${new Date(userInput)}`
const d = new Date(userInput); Number.isNaN(d.getTime()) ? "—" : `Due: ${d}`
new Date(0).toGMTString()
new Date(0).toUTCString()
When to use
- HTTP date headers, where toUTCString is the required format
- Logs and debug output, where a fixed English shape is fine
- Quick inspection in a console
- Anything a user reads → the toLocale* family
- Storing or transmitting → toISOString
- Parsing back → these formats are not reliably parseable
- toGMTString → use toUTCString
Notes
FAQ
toUTCString for HTTP headers, because that is the format the specification requires. toISOString for storage. The toLocale* family for users. toString only in logs and the console — and it runs implicitly whenever a Date meets a template literal.