Quirks of the JavaScript Date Format

JavaScript provides a Date Object and a variety of methods by which it may be interrogated. Unfortunately browser manufacturers all seem to have their own ideas about how the results should be formatted. So any attempt to manipulate this data is apt to result in a mess. I have found that most standard JavaScript reference works quietly ignored this problem. So I have produced this page in the hope it may help others who have fallen into the same mire. . . . . and all I was originally setting out to do, was to include a page's last-updated date in a tidy format!

We begin by demonstrating the results produced by some of the methods of the Date Object, for various browsers, starting with the one you are using to view this page. The other browsers are a collection, of various vintages, which I happen to have on my computer. The computer is running Windows 98SE and Regional Settings are configured to standard UK English, with Date format set to DD/MM/YY. (Note how the "toLocale" method has completely ignored this!)

The date and time chosen for this first example is 1:30 AM on the 19th January 2005, and this has been defined by:

testDate = new Date(2005,0,19,1,30,00)

This is how Your Browser renders the test date

This is how Internet Explorer Version 5.0 renders the test date
Raw printing of Date Object Wed Jan 19 01:30:00 UTC 2005
Effect of the   toString()   method Wed Jan 19 01:30:00 UTC 2005
Effect of the   toUTCString()   method Wed, 19 Jan 2005 01:30:00 UTC
Effect of the   toGMTString()   method Wed, 19 Jan 2005 01:30:00 UTC
Effect of the   toLocaleString()   method 01/19/2005 01:30:00

This is how Internet Explorer Versions 5.5 to 7.0 render the test date
Raw printing of Date Object Wed Jan 19 01:30:00 UTC 2005
Effect of the   toString()   method Wed Jan 19 01:30:00 UTC 2005
Effect of the   toUTCString()   method Wed, 19 Jan 2005 01:30:00 UTC
Effect of the   toGMTString()   method Wed, 19 Jan 2005 01:30:00 UTC
Effect of the   toLocaleString()   method 19 January 2005 01:30:00

This is how Netscape Version 4.04 renders the test date
Raw printing of Date Object Wed Jan 19 01:30:00 GMT Standard Time 2005
Effect of the   toString()   method Wed Jan 19 01:30:00 GMT Standard Time 2005
Effect of the   toUTCString()   method Wed, 19 Jan 2005 01:30:00 GMT
Effect of the   toGMTString()   method Wed, 19 Jan 2005 01:30:00 GMT
Effect of the   toLocaleString()   method 01/19/05 01:30:00

This is how Opera Version 7.54 renders the test date
Raw printing of Date Object Wed, 19 Jan 2005 01:30:00 GMT+0000
Effect of the   toString()   method Wed, 19 Jan 2005 01:30:00 GMT+0000
Effect of the   toUTCString()   method Wed, 19 Jan 2005 01:30:00 GMT
Effect of the   toGMTString()   method Wed, 19 Jan 2005 01:30:00 GMT
Effect of the   toLocaleString()   method Wed, 19 Jan 2005 01:30:00 GMT+0000

This is how Mozilla Firefox Version 1.0 renders the test date
Raw printing of Date Object Wed Jan 19 2005 01:30:00 GMT+0000 (GMT Standard Time)
Effect of the   toString()   method Wed Jan 19 2005 01:30:00 GMT+0000 (GMT Standard Time)
Effect of the   toUTCString()   method Wed, 19 Jan 2005 01:30:00 GMT
Effect of the   toGMTString()   method Wed, 19 Jan 2005 01:30:00 GMT
Effect of the   toLocaleString()   method Wednesday, January 19, 2005 01:30:00

This is how Mozilla Firefox Version 2.0 renders the test date
Raw printing of Date Object Wed Jan 19 2005 01:30:00 GMT+0000 (GMT Standard Time)
Effect of the   toString()   method Wed Jan 19 2005 01:30:00 GMT+0000 (GMT Standard Time)
Effect of the   toUTCString()   method Wed, 19 Jan 2005 01:30:00 GMT
Effect of the   toGMTString()   method Wed, 19 Jan 2005 01:30:00 GMT
Effect of the   toLocaleString()   method 19 January 2005 01:30:00

These tests show that at least on the browsers I have to hand, raw printing of the Date Object always uses the toString method, and that the toGMTString and toUTCString methods produce identical results. So only the three distinct methods have been shown for the results which follow.

The format details change slightly if the date is in British Summertime (Daylight Saving Time). Thus for a date in June for example:

testDate = new Date(2005,5,29,15,20,00)

This is how Your Browser renders the test date

This is how Internet Explorer Version 5.0 renders the test date
Effect of the   toString()   method Wed Jun 29 15:20:00 UTC+0100 2005
Effect of the   toGMTString()   method Wed, 29 Jun 2005 14:20:00 UTC
Effect of the   toLocaleString()   method 06/29/2005 15:20:00

This is how Internet Explorer Versions 5.5 to 7.0 render the test date
Effect of the   toString()   method Wed Jun 29 15:20:00 UTC+0100 2005
Effect of the   toGMTString()   method Wed, 29 Jun 2005 14:20:00 UTC
Effect of the   toLocaleString()   method 29 June 2005 15:20:00

This is how Netscape Version 4.04 renders the test date
Effect of the   toString()   method Wed Jun 29 15:20:00 GMT Daylight Time 2005
Effect of the   toGMTString()   method Wed, 29 Jun 2005 13:20:00 GMT
Effect of the   toLocaleString()   method 06/29/05 15:20:00

This is how Opera Version 7.54 renders the test date
Effect of the   toString()   method Wed, 29 Jun 2005 15:20:00 GMT+0100
Effect of the   toGMTString()   method Wed, 29 Jun 2005 14:20:00 GMT
Effect of the   toLocaleString()   method Wed, 29 Jun 2005 15:20:00 GMT+0100

This is how Mozilla Firefox Version 1.0 renders the test date
Effect of the   toString()   method Wed Jun 29 2005 15:20:00 GMT+0100 (GMT Daylight Time)
Effect of the   toGMTString()   method Wed, 29 Jun 2005 14:20:00 GMT
Effect of the   toLocaleString()   method Wednesday, June 29, 2005 15:20:00

This is how Mozilla Firefox Version 2.0 renders the test date
Effect of the   toString()   method Wed Jun 29 2005 15:20:00 GMT+0100 (GMT Daylight Time)
Effect of the   toGMTString()   method Wed, 29 Jun 2005 14:20:00 GMT
Effect of the   toLocaleString()   method 29 June 2005 15:20:00

The conclusion thus far is that using the method toGMTString (or toUTCString) produces consistent results across all the browsers tried, if we ignore the difference between UTC and GMT at the end of the string.

But we are not fully out of the wood yet! Remember the initial objective was to produce a tidily formatted "last updated" message for a page. The standard way to determine this date is to use the lastModified property of the Document object, thus:

testDate = new Date(document.lastModified)

Most modern browsers get this right and the formatting is as above, but look what happens with Netscape 4, (and maybe some other pre-millennium browsers that may still be in use), for a document modified in 2005. A mere 100 years out!

This is how Your Browser renders the document.lastModified date

This is how Netscape Version 4.04 renders the document.lastModified date
Effect of the   toString()   method Mon Mar 27 17:35:26 GMT Standard Time 1905
Effect of the   toGMTString()   method Mon, 27 Mar 1905 17:35:26 GMT
Effect of the   toLocaleString()   method 03/27/05 17:35:26

So a little more code is needed to detect and correct this "quirk" of older browsers.

This brings us eventually to code like the following fragment of JavaScript, which seems to give a consistent results across all the browsers I have tried:

da = new Date(document.lastModified) // Create a Date Object set to the last modifed date
db = da.toGMTString() // Convert to a String in "predictable formt"
dc = db.split(" ") // Split the string on spaces
if ( eval( dc[3] ) < 1970 ) dc[3] = eval( dc[3] ) +100 // Correct any date purporting to be before 1970
db = dc[1] + " " + dc[2] + " " + dc[3] // Ignore day of week and combine date, month and year
document.write ( "Last Updated " + db ) // Display the result

This is the result, as displayed by your browser:

An alternative approach is to use the various "get" methods of the Date Object to obtain numeric values for the date, month and year. These can then be reassembled to produce a date string in a chosen format. This is probably the easiest way to produce a standard ISO format date for example, using the following code;

da = new Date(document.lastModified) // Create a Date Object set to the last modifed date
dy = da.getFullYear() // Get full year (as opposed to last two digits only)
dm = da.getMonth() + 1 // Get month and correct it (getMonth() returns 0 to 11)
dd = da.getDate() // Get date within month
if ( dy < 1970 ) dy = dy + 100; // We still have to fix the millennium bug
ys = new String(dy) // Convert year, month and date to strings
ms = new String(dm)  
ds = new String(dd)  
if ( ms.length == 1 ) ms = "0" + ms; // Add leading zeros to month and date if required
if ( ds.length == 1 ) ds = "0" + ds;  
ys = ys + "-" + ms + "-" + ds // Combine year, month and date in ISO format
document.write ( "Last Updated " + ys ) // Display the result

Again, here is the result, as displayed by your browser:

It is my hope that everyone viewing this page will see both these dates formatted correctly. If this is not the case, I would be interested to receive an email describing the problems encountered plus details of the browser and operating system in use.

Both the techniques described above, should work without needed to resort to detecting the browser in use, in order to select different code options. There are standard "browser detection" techniques which would permit this if required. However these are becoming almost useless as many browsers now have the option to "pretend" to be a different make or model, without of course ensuring that their behaviour mimics all aspects of the browser they are claiming to mimic.


Copyright © Alan Simpson 2005 Back to index.