PDA

View Full Version : Detect Cookie's Age



jscheuer1
11-19-2005, 11:10 PM
I recently made another foray into using cookies and discovered that there is generally (at least as far as I could tell) no way to query document.cookie and find out when a specific value expires. I devised a way to do this and thought folks might be interested. It builds on the cookie unit (included here for clarity) found on Quirksmode dot org (http://www.quirksmode.org). It relies on the fact that, since you set the cookie value in the first place, there is no reason why you cannot set another value which contains its expiration and query that value later to find out how much time is left (I used days as a reasonable time period to express things in, other time units could be used, if preferred):


//Begin http://www.quirksmode.org Cookie Code:

function createCookie(name,value,days) //modified by jscheuer1 to store expire date (if any) in retrievable form and later calculate days remaining
{
if (days)
{
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
var setAt=Date.parse(date.toGMTString()) // new
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
if (days) // these two lines new
document.cookie = name+"set="+setAt+expires+"; path=/";
}

function readCookie(name)
{
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++)
{
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}

function dateCookie(name) //Expires in ? days function added - jscheuer1
{
var nameEQ = name + "set=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++)
{
var date=new Date()
date=Date.parse(date.toGMTString())
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return Math.ceil((Math.abs(c.substring(nameEQ.length,c.length))-date)/(24*60*60*1000));
}
return null;
}

function eraseCookie(name)
{
createCookie(name,"",-1);
}

//End http://www.quirksmode.org Cookie Code

The dateCookie function accepts the cookie name as a parameter and returns the time (rounded up to the nearest amount of days) left before the cookie expires, if the cookie exists and is that type otherwise, null is returned.

Twey
11-20-2005, 09:08 AM
A good idea. Easier than setting multitudes of cookies for a progressing date (e.g. a countdown).

mwinter
11-20-2005, 04:00 PM
I recently made another foray into using cookies and discovered that there is generally (at least as far as I could tell) no way to query document.cookie and find out when a specific value expires.Correct. It's not at all possible. However, that's because the point of expiry is irrelevant.

The lifetime of a cookie should reflect the utility of its data: the cookie should only expire when it's of no more use. If a particular time or date is of interest, for whatever reason, it should be stored as separate data. That is effectively what you're doing, but I don't think it should be an intrinsic operation.

Mike

jscheuer1
11-21-2005, 04:00 AM
If a particular time or date is of interest, for whatever reason, it should be stored as separate data. That is effectively what you're doing, but I don't think it should be an intrinsic operation.

Agreed, this is just for those times when it is desirable, I should have made that clear.

mwinter
11-21-2005, 12:25 PM
A couple of things I forgot to mention:


var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));

var date = new Date();
date.setUTCDate(date.getUTCDate() + days);



var expires = "; expires="+date.toGMTString();The usual behaviour of the toGMTString method isn't (technically) appropriate for cookies as it doesn't produce the correct format. It should be replaced by:



Date.prototype.toGMTString = (function() {
var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

return function() {
return [days[this.getUTCDay()], ', ',
this.getUTCDate().pad(2), '-',
months[this.getUTCMonth()], '-',
this.getUTCFullYear().pad(4), ' ',
this.getUTCHours().pad(2), ':',
this.getUTCMinutes().pad(2), ':',
this.getUTCSeconds().pad(2), ' GMT'].join('');
};
})();



var setAt=Date.parse(date.toGMTString())That's a rather round-about way of getting the time in milliseconds. Either convert the object to a number,



var setAt = +date;
call valueOf, or call getTime.


while (c.charAt(0)==' ') c = c.substring(1,c.length);I'd define a trim method (or similar):



String.prototype.ltrim = function() {
return String(this).replace(/^\s+/, '');
};
Alternatively, I'd use a regular expression to search and parse the string:



function readCookie(name) {
var pattern = new RegExp('(^|;)\\s*' + nameEQ + '\\s*=\\s*([^\\s;]+)', 'g'),
cookie;

return (cookie = pattern.exec(document.cookie))
? cookie[2]
: null;
}
Mike