I am storing a datetime value in a cookie using ASP.Net server-side C# code. On client-side, I am reading the date and converting it to UTC using JavaScript. The code for this is as given below.
Storing date time in ASP.Net
//DateTime.Now depends on location of web server
HttpCookie cookie = new HttpCookie("xyz", DateTime.Now.ToUniversalTime().ToString());
Response.Cookies.Add(cookie);
JavaScript code to read date time sent by ASP.Net
//cDate depends on user's location
//c is value read from cookie named 'xyz'
var cDate = new Date(c);
var cDate_utc = new Date(cDate.getUTCFullYear(), cDate.getUTCMonth(), cDate.getUTCDate(), cDate.getUTCHours(), cDate.getUTCMinutes(), cDate.getUTCSeconds());
When the end user's location is different from ASP.Net web server's location, then the datetime value in the cookie will be incorrectly interpreted by JavaScript. For example, in one case the value stored in cookie was 10/31/2015 7:29:54 PM
and there is no way for JavaScript to know that this is UTC which means it would be incorrectly parsed on client-side.
Question: How can I pass DateTime value from ASP.Net to JavaScript in above scenario so it interprets correctly in JavaScript no matter what the geographical locations of end user's browser and ASP.Net web server are?
UPDATE with a solution that worked
After a lot of research, I came up with the following. The bottom line is to always work in UTC so day light savings does not cause problems with the programming logic.
- Pass UTC and not local date time from ASP.Net server-side to client-side via a cookie using individual components of date time. Do not pass a date time string but individual components of date time as a comma-delimited list in following format:
year,month, day, hours, min, sec, milliseconds
. Passing individual components rather than a date time string from ASP.Net is better since JavaScript Date constructor can behave in an erratic manner when parsing a string especially if the format of string passed is not what the constructor likes. Passing individual components also helps in cross-browser consistent behavior since the Date constructor with individual components works well across all major browsers. - On client-side, read the cookie value and instantiate a Date object that will be the local time on browser side corresponding to server-side UTC time
- Now you have the server-side ASP.Net passed date time in local date time on client-side. This might work for some cases, but can cause sudden surprises on client-side when daylight savings happens, so it's best to convert this client-side date to UTC.
Pass date time in UTC to client-side from ASP.Net
DateTime utcDateTime = DateTime.Noe.ToUniversalTime();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append(utcDateTime.Year);
sb.Append(",");
sb.Append(utcDateTime.Month - 1); //since JavaScript uses a 0 based index for month
sb.Append(",");
sb.Append(utcDateTime.Day);
sb.Append(",");
sb.Append(utcDateTime.Hour);
sb.Append(",");
sb.Append(utcDateTime.Minute);
sb.Append(",");
sb.Append(utcDateTime.Second);
sb.Append(",");
sb.Append(utcDateTime.Millisecond);
HttpCookie cookie = new HttpCookie("xyz", sb.ToString());
Response.Cookies.Add(cookie);
Get UTC date time in JavaScript for passed ASP.Net date time
var c = getCookie("xyz");//getCookie is a custom JavaScript function to read cookie value
if (c) {
var dateArray = c.split(",");
//get local date time corresponding to ASP.Net passed UTC date time
var cDate = new Date( Date.UTC(dateArray[0], dateArray[1],dateArray[2], dateArray[3], dateArray[4], dateArray[5], dateArray[6])) ;
//get UTC date time so day light savings does not cause issues in logic on client-side
cDate_utc = new Date(cDate.getUTCFullYear(), cDate.getUTCMonth(), cDate.getUTCDate(), cDate.getUTCHours(), cDate.getUTCMinutes(), cDate.getUTCSeconds());
logInfo("date from cookie in utc is " + cDate_utc);
}