ParseCookieDate(string dateString, out DateTime dtOut) {
//
// The format variants
//
// 1) .NET HttpCookie = "dd-MMM-yyyy HH:mm:ss GMT'"
// 2) Version0 = "dd-MMM-yy HH:mm:ss GMT"
// 3) Some funky form = "dd MMM yyyy HH:mm:ss GMT"
//
// In all above cases we also accept single digit dd,hh,mm,ss
// That's said what IE does.
dtOut = DateTime.MinValue;
char[] buffer = dateString.ToCharArray();
char ch;
if (buffer.Length < 18) { //cover all before "ss" in the longest case
return false;
}
int idx = 0;
// Take the date
int day=0;
if (!Char.IsDigit(ch = buffer[idx++])) {return false;}
else {day = ch-'0';}
if (!Char.IsDigit(ch = buffer[idx++])) {--idx;} //one digit was used for a date
else {day = day*10 +(ch-'0');}
if (day > 31) {return false;}
++idx; //ignore delimiter and position on Month
// Take the Month
int month = MapDayMonthToDword(buffer, idx);
if (month == DATE_TOKEN_ERROR) {return false;}
idx+=4; //position after Month and ignore delimiter
// Take the year
int year=0;
int i;
for (i=0; i < 4; ++i) {
if (!Char.IsDigit(ch = buffer[i+idx])) {
// YY case
if (i != 2) {return false;}
else {break;}
}
year = year*10 + (ch-'0');
}
//check for two digits
if (i == 2) {
year += ((year < 80) ? 2000 : 1900);
}
i += idx; //from now on 'i' is used as an index
if (buffer[i++] != ' ') {return false;}
//Take the hour
int hour=0;
if (!Char.IsDigit(ch = buffer[i++])) {return false;}
else {hour = ch-'0';}
if (!Char.IsDigit(ch = buffer[i++])) {--i;} //accept single digit
else {hour = hour*10 +(ch-'0');}
if (hour > 24 || buffer[i++] != ':') {return false;}
//Take the min
int min=0;
if (!Char.IsDigit(ch = buffer[i++])) {return false;}
else {min = ch-'0';}
if (!Char.IsDigit(ch = buffer[i++])) {--i;} //accept single digit
else {min = min*10 +(ch-'0');}
if (min > 60 || buffer[i++] != ':') {return false;}
//Check that the rest will fit the buffer size "[s]s GMT"
if ((buffer.Length - i) < 5) {return false;}
//Take the sec
int sec=0;
if (!Char.IsDigit(ch = buffer[i++])) {return false;}
else {sec = ch-'0';}
if (!Char.IsDigit(ch = buffer[i++])) {--i;} //accept single digit
else {sec = sec*10 +(ch-'0');}
if (sec > 60 || buffer[i++] != ' ') {return false;}
//Test GMT
if((buffer.Length - i) < 3 || buffer[i++] != 'G' || buffer[i++] != 'M' || buffer[i++] != 'T') {
return false;
}
dtOut = new DateTime (year, month, day, hour, min, sec, 0).ToLocalTime();
return true;
}
}