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.

Date methodsES1 (1997)Live demo
Common call
d.toUTCString()
Returns
'Sun, 15 Mar 2026 12:00:00 GMT'
Replaces
nothing; Intl replaces IT for user-facing output
Watch out
always English, and toString embeds the local zone
date.toString(), date.toUTCString(), date.toDateString()
→ string

Demo

Live evaluation
Try:
Inputs
isostringan ISO date
Output
new Date('2026-03-15T12:00:00Z').toUTCString()
'Sun, 15 Mar 2026 12:00:00 GMT'

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

An HTTP date header
This is the specified format.
res.setHeader('Last-Modified', d.toUTCString());
Debug output
toString is what a template literal gives you.
console.log(`${d}`);   // calls toString
Anything user-facing
Use a locale format instead.
d.toLocaleDateString('en-GB', {dateStyle: 'long'});

Examples

1. HTTP format
new Date('2026-03-15T12:00:00Z').toUTCString()
Returns
'Sun, 15 Mar 2026 12:00:00 GMT'
2. The epoch
new Date(0).toUTCString()
Returns
'Thu, 01 Jan 1970 00:00:00 GMT'
3. Invalid is a string
new Date('nonsense').toString()
Returns
'Invalid Date'
4. toISOString throws
new Date('nonsense').toISOString()
Returns
RangeError: Invalid time value
5. toString is local
new Date('2026-03-15T12:00:00Z').toString()
Returns
includes the runtime zone, e.g. 'GMT+0200 (…)'
6. toGMTString is an alias
Date.prototype.toGMTString === Date.prototype.toUTCString
Returns
true

Pitfalls

1. They are always English
Day and month abbreviations are fixed by the specification, so these formats never localise. A date rendered with toDateString shows "Sun 15 Mar 2026" to a German reader too, which looks like a bug in your product.
English only
new Date('2026-03-15T12:00:00Z').toDateString()
'Sun Mar 15 2026'
Localised
new Date('2026-03-15T12:00:00Z').toLocaleDateString('de-DE')
'15.3.2026'
2. toString output is not fully specified
The shape is defined but the trailing timezone name in parentheses is implementation-dependent, and it reflects the runtime zone. Never parse it, and never assert on it in a test.
Runtime-dependent
new Date(0).toString()
differs by machine
Stable
new Date(0).toISOString()
'1970-01-01T00:00:00.000Z'
3. This is where [object Date] never appears — but Invalid Date does
A Date in a template literal calls toString, so an unparseable date renders as the literal text "Invalid Date" in your UI rather than failing loudly. Validate before formatting.
Shows in the UI
`Due: ${new Date(userInput)}`
'Due: Invalid Date'
Check first
const d = new Date(userInput);
Number.isNaN(d.getTime()) ? "—" : `Due: ${d}`
'—'
4. toGMTString is the same function as toUTCString
Not merely similar — Annex B defines it as an alias, so they are one function object under two names. It exists only for old code and should never appear in new.
Legacy name
new Date(0).toGMTString()
works, but Annex B
Standard name
new Date(0).toUTCString()
identical output

When to use

Use it
  • 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
Reach for something else
  • Anything a user reads → the toLocale* family
  • Storing or transmitting → toISOString
  • Parsing back → these formats are not reliably parseable
  • toGMTString → use toUTCString

Notes

Complexity
O(1)
Return
A new string; the Date is unchanged
CPython impl
V8: Builtins-date-tostring
Memory
Allocates the result string
Thread-safe
Single-threaded

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.

History

ES1
toString, toDateString, toTimeString, toUTCString and toGMTString present from the first version.
ES5
toGMTString relegated to Annex B as an alias of toUTCString; toISOString added.
ES2018
The toString format specified precisely, apart from the implementation-dependent timezone name.