16

I have an ASP.NET application running on a server in California. The server's current time is:

  • 7/20/2015 14:00 UTC-08:00

Bob is connected to my server. Bob is in Texas. His current time is:

  • 7/20/2015 16:00 UTC-06:00

My application creates a cookie and set its expiration date.

var name = "MyName";
var value = "MyValue"
var hoursToLive = 24;

var myCookie = new HttpCookie(name )
{
    Value = value,
    Expires = DateTime.Now.AddHours(hoursToLive)
};

Will the cookie expire in 24 hours, or will it expire in 22 hours due to the time difference between Bob and the server? I know that DateTime.Now uses the server's local time, but I am unclear as to how browsers decide that a cookie is expired (specifically, what time zone is used to determine expiration).

Community
  • 1
  • 1
Rainbolt
  • 3,542
  • 1
  • 20
  • 44
  • 1
    why not try it with an expiration of 2 hours and see if it expires immediately? –  Jul 20 '15 at 21:22
  • @AndreasNiedermair Deploying the product is tedious (i.e., it takes hours), and I'd like to know what to expect before I go through that pain. – Rainbolt Jul 20 '15 at 21:24
  • make a little demo app, and use a VM with a different timezone? –  Jul 20 '15 at 21:25
  • @AndreasNiedermair That's a good idea. – Rainbolt Jul 20 '15 at 21:25
  • Cookies are sent to the browser with an expires attribute like: `Expires=Wed, 09 Jun 2021 10:18:14 GMT`. I've never tested it, but browsers should be able to handle that fine and expire it 24 hours after it's sent. – David Sherret Jul 20 '15 at 21:32
  • @DavidSherret if the timezone is included, the client can cope with the offset correctly, making the cookie expire correctly after 24 hours. –  Jul 20 '15 at 21:34
  • @AndreasNiedermair I meant to write 24 hours—not 22 (I just fixed it). But yeah, since the time zone is sent it should be no problem. – David Sherret Jul 20 '15 at 21:34

2 Answers2

18

Cookies do include a timezone information with the expires header (mostly GMT), which makes it quite simple for the client to cope with the offset to the server's actual timezone.

Example: expires=Mon,20-Jul-2015 22:00:00 GMT if 2015-07-20 14:00:00 UTC-8 is the server's time. When the client or server decides whether the cookie is expired or not, it will compare it to the associated GMT time.

I dug deeper into the code of System.Web.HttpCookie, and found the relevant code in GetSetCookieHeader():

        if (_expirationSet && _expires != DateTime.MinValue) {
            s.Append("; expires=");
            s.Append(HttpUtility.FormatHttpCookieDateTime(_expires));
        }

Where HttpUtility.FormatHttpCookieDateTime() returns a UTC timestamp (with no offset, which doesn't matter because the offset would be zero).

Greenwich Mean Time (GMT) and Coordinated Universal Time (UTC) can, for most purposes, be considered the same. You can read more about this here.

Community
  • 1
  • 1
  • I deployed a demo app to my dev machine and got another developer to connect to it. His machine was two hours ahead of mine, and I set a cookie to expire after `DateTime.Now.AddHours(2)`. The cookie did not expire immediately, which lines up with what you describe in your answer. Thank you for your helpful suggestion in the comments on the question. I'll accept your answer tomorrow if nobody contradicts it. – Rainbolt Jul 20 '15 at 22:32
  • @Rainbolt thanks for your edit, but the UT is not really needed, as *universal timestamp* means UTC (see http://referencesource.microsoft.com/#mscorlib/system/datetime.cs,fddce8be2da82dfc,references). –  Jul 27 '15 at 15:28
  • No problem. Yea, I see now that `ToUniversalTime()` calls `ConvertTimeToUtc()`. The source of my confusion was terminology, and so I wanted the answer to have totally clear terminology (in case others like me find this place). I made another edit in that spirit, because it wasn't clear to me what a "universal timestamp" was. – Rainbolt Jul 27 '15 at 15:41
0

Your cookie will expire at exactly the same moment in time for everyone...

...just at different local times shown on their clocks based on their timezones. So for example, people who got cookies at exactly the same moment in California and Texas, those users will see their cookies expired at the same moment in time, just not the same time shown on their clocks. For Bob it will be 4:pm but in California it will be 2:pm. Same point in time, just different clocks at different times of the day for each person using your website.

Cookies all save DateTime expiration values in UTC or Universal Coordinated Time which is in Greenwich, London, UK (England). When users store cookies in their browsers, all their cookie expiration date-times are in ISO-UTC format and have a "Z" or "GMT" at the end to indicate they are using this UTC value. Even though they may look different for different local times around the world, they include an offset that maps them back to UTC. This means when you set a DateTime for two different users at the same time in different time zones, they both will expire at the same point in time, just not the same local time shown on clocks in both zones.

However...

If you wanted each person's cookie to expire at say midnight relative to their time zone, then yes, you would need to first get the local time of midnight for their local computer using JavaScript, then translate that to UTC. Create a cookie in JavaScript from that using document.cookie. Now they havea cookie that ends at midnight only in their time zone.

Another option...

If you wanted to have everyone around the world have cookies that expire relative to a specific timezone clock at say, midnight in California, then yes...you would need to get the exact datetime in California you want the rest of the world to use in your cookie logic and translate that to UTC datetime. Store that value on the server, then set it as the cookie expiration for all user cookies visiting your website. When midnight in California occurs, everyone's cookie around the world expires at the same time again, but to that same UTC value which matches midnight in California.

Stokely
  • 12,444
  • 2
  • 35
  • 23