Last modified date

This script does not work in Netscape 2, Explorer 3 on Mac, Hotjava 3, Konqueror, and Netscape 4 on Linux for a variety of reasons.

Explorer 3 gives a date 17 hours too early. Don't yet know what's causing it.

Opera and Explorer 4 don't take time zones and daylight saving time into account and give a last Modified date of (in the case of this page) two hours too early.

WebTV gives only a last modified day, no hours.

Many thanks to Romek Zylla for helping to determine the exact lastModified problems in several browsers.

This script will give your users information on how long ago the document they're reading was last modified. In addition, it does so in a user friendly way.
I use the script myself at the top of each page in this site.

This script centers on document.lastModified, a JavaScript property that gives the last modification date of the page. In order for this property to work, the server has to send the information to the browser. Fortunately most servers do so nowadays.

However, if they don't you can expect trouble. Research by Romek Zylla and myself shows that when a server does not send a lastModified date, Netscape and Opera give a last modification date of 01/01/1970 at 00:00:00 hrs (the start of Epoch Time), while Explorer gives today. So always test the server your pages are on before using this script.

You can view the HTTP header (in which the last modified date should be included) of your pages through http://www.delorie.com/web/headers.html. If the line 'Last-Modified: [date]' is missing, your server does not send the date and you should not use this script.

In addition, Netscape has a grave bug when reading out the year from the last modification date: it is exactly one century too early. (See the Introduction page for more information). Fortunately the script evades this bug.

Finally, Opera and Explorer 4 give a date two hours too early, while Explorer 3 even makes it 17 hours early. The Explorer 4 error seems to be that it doesn't take time zones and daylight saving time into account. My server returns a GMT time and Explorer 4 literally copies it, while Netscape and Explorer 5 calculate local time.

document.lastModified

If you don't want any user friendly output, you're ready very quickly. Do

document.write(document.lastModified);

and the date is printed. The output differs per browser. Yours gives .

However, I resolved to make the script nicer by saying how many days (or weeks or months) have passed since the document was last modified. This makes the script far more complex, but I think the result is worth the trouble.

So I read out document.lastModified, compare this date to the current date, create some user friendly output and I'm ready.

The script

function lastMod()
{
	var x = new Date (document.lastModified);
	Modif = new Date(x.toGMTString());
	Year = takeYear(Modif);
	Month = Modif.getMonth();
	Day = Modif.getDate();
	Mod = (Date.UTC(Year,Month,Day,0,0,0))/86400000;
	x = new Date();
	today = new Date(x.toGMTString());
	Year2 = takeYear(today);
	Month2 = today.getMonth();
	Day2 = today.getDate();
	now = (Date.UTC(Year2,Month2,Day2,0,0,0))/86400000;
	daysago = now - Mod;
	if (daysago < 0) return '';
	unit = 'days';
	if (daysago > 730)
	{
		daysago = Math.floor(daysago/365);
		unit = 'years';
	}
	else if (daysago > 60)
	{
		daysago = Math.floor(daysago/30);
		unit = 'months';
	}
	else if (daysago > 14)
	{
		daysago = Math.floor(daysago/7);
		unit = 'weeks'
	}
	var towrite = 'Page last changed ';
	if (daysago == 0) towrite += 'today';
	else if (daysago == 1) towrite += 'yesterday';
	else towrite += daysago + ' ' + unit + ' ago';
	return towrite;
}


function takeYear(theDate)
{
	x = theDate.getYear();
	var y = x % 100;
	y += (y < 38) ? 2000 : 1900;
	return y;
}

and finally at the place where it should be written

document.write(lastMod())

Explanation

We start by taking document.lastModified and making this string a Date object.

var x = new Date (document.lastModified);

Then we change the time to GMT, so that the comparision between two dates is valid. After all, your user may be in another time zone than your server. The GMTString is a string, so we have to make it a Date object again.

Modif = new Date(x.toGMTString());

Then we take the year with the function described on the Introduction page:

Year = takeYear(Modif);

function takeYear(theDate)
{
	x = theDate.getYear();
	var y = x % 100;
	y += (y < 38) ? 2000 : 1900;
	return y;
}

Take the month, the day, then calculate the number of milliseconds and divide by 86,400,000 to get the day number since the beginning of Epoch Time. (This code is explained in more detail on the week number page). We put this day number in Mod.

Month = Modif.getMonth();
Day = Modif.getDate();
Mod = (Date.UTC(Year,Month,Day,0,0,0))/86400000;

Then do the same for the current date and put the day number in now.

x = new Date();
today = new Date(x.toGMTString());
Year2 = takeYear(today);
Month2 = today.getMonth();
Day2 = today.getDate();
now = (Date.UTC(Year2,Month2,Day2,0,0,0))/86400000;

Subtract Mod from now to get the number of days since the document was last modified.

daysago = now - Mod;

If daysago is less than zero (because the user has a wrong system time, for instance), return an empty string so that the script doesn't print out a negative number of days.

if (daysago < 0) return '';

Output

If you only want to print out the number of days, do

return daysago

and end the script. However, I decided to give a slightly different output. My reason was that I want to give an output that people can relate to, instead of just a number of days that may be quite large. If you say 'Page last changed 107 days ago', people may get confused, but if you say 'Page last changed 3 months ago' they know exactly what you're talking about. Granted, the difference is purely psychological, but I like the script better the way I wrote it.

So I decided to give the number of days only if it's less than 15, then the number of weeks if it's less than 9, then the number of months if it's less than 25, and then the number of years. I only do a rough-and-ready calculation. If you wish, you can modify the calculation to suit your own needs.

I create a new variable unit and start calculating:

unit = 'days';
if (daysago > 730)
{
	daysago = Math.floor(daysago/365);
	unit = 'years';
}
else if (daysago > 60)
{
	daysago = Math.floor(daysago/30);
	unit = 'months';
}
else if (daysago > 14)
{
	daysago = Math.floor(daysago/7);
	unit = 'weeks'
}

Then finally start making a string towrite which is returned to the document.write(lastMod()) command and is written into the page. First some overhead to make it look nice, then two special cases for today and yesterday, finally print out daysago followed by the correct unit. Return this string and you're ready.

var towrite = 'Page last changed ';
if (daysago == 0) towrite += 'today';
else if (daysago == 1) towrite += 'yesterday';
else towrite += daysago + ' ' + unit + ' ago';
return towrite;