Home:ALL Converter>determining the beginning of a day with timezones AND daylight saving

determining the beginning of a day with timezones AND daylight saving

Ask Time:2011-09-12T07:01:21         Author:frenchie

Json Formatter

I'm storing the user's timezone as a decimal in the session. For instance, if the user is in the EST timezone, I'd have

UserTimeZone = -5.00;

The data in the database is stored in UTC, so I want to calculate the beginning and the end of the day for that user so that when the user wants his data for a specific day, the records are timezone adjusted.

This is what I'm doing:

DateTime StartDate =  DateTime.Now.ToUniversalTime();

StartDate = StartDate.AddHours((double)UserTimeZone);
StartDate = StartDate.Date;
StartDate = StartDate.AddHours((double)UserTimeZone);

DateTime EndDate = StartDate.AddHours(24);

The problem I'm having is that this doesn't account for daylight saving time so even thought EST time is 5 hours behind UTC, for the moment it's actually 4 hours behind UTC because of the daylight saving shift.

What are some of your suggestions? Thanks.

Author:frenchie,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/7381865/determining-the-beginning-of-a-day-with-timezones-and-daylight-saving
Erik Funkenbusch :

You shouldn't be doing any of this. You should just use the TimeZoneInfo built into .net.\n\nFor example:\n\nTimeZoneInfo.ConvertTimeToUtc();\nTimeZoneInfo.ConvertTimeFromUtc();\n\n\nSince you don't seem able to lookup API Parameters, here you go:\n\nhttp://msdn.microsoft.com/en-us/library/system.timezoneinfo.converttimefromutc.aspx\n\nhttp://msdn.microsoft.com/en-us/library/bb381744.aspx",
2011-09-17T19:32:46
Jon :

To make such calculations you will need to use the TimeZoneInfo and DateTimeOffset classes.\n\nFirst of all, we need to get a TimeZoneInfo instance for both the local time and the user's local time:\n\nvar localTimezone = TimeZoneInfo.Local;\nvar userTimezone = TimeZoneInfo.FindSystemTimeZoneById(\"Eastern Standard Time\");\n\n\nThe caveat here is that you need to know the id of the user's local timezone (the offset that you currently have is not going to be enough). You can get a list of all TimeZoneInfo instances that the system recognizes with TimeZoneInfo.GetSystemTimeZones, and then you need a way of matching the user-provided timezone with one of those.\n\nFor this example, I have hardcoded EST.\n\nThen you need to get a DateTimeOffset instance for today's midnight (start of day) in your local timezone:\n\nvar todayDate = DateTime.Today;\nvar todayLocal = new DateTimeOffset(todayDate,\n localTimezone.GetUtcOffset(todayDate));\n\n\nGiven this, you can calculate the DateTimeOffset instance that represents the midnight of \"today\" (based on your local time) in the user's timezone. Be aware that, depending on timezones, this may actually be in the future for the user's timezone!\n\nvar todayUser = TimeZoneInfo.ConvertTime(todayLocal, userTimezone);\n\n\nAnd finally, you can create timestamps for both dates like this:\n\nvar epochStart = DateTime.Parse(\"01/01/1970 00:00:00\");\nvar todayLocalTs = (todayLocal.Ticks - epochStart.Ticks)/TimeSpan.TicksPerSecond;\nvar todayUserTs = (todayUser.Ticks - epochStart.Ticks) / TimeSpan.TicksPerSecond;\n",
2011-09-18T15:15:44
Daniel B :

As BrokenGlass mentioned, a simple offset is not enough information to determine the handling of daylight hours, since different countries in each zone might handle daylight savings differently. The C# TimeZone class is more specific, and has support for daylight savings (check details on MSDN). Unfortunately there is no easy way to get the relevant timezone from the browser, but there are several suggestions on this post regarding how you can allow the user to pick their timezone.\n\nIf you want to try and work out the timezone without the user's assistance, there are a few ways to do that (typically revolving around getting the browser's preferred language, and then mapping that to a country...), some examples are here and here.",
2011-09-12T06:03:25
Yahia :

You will need to use JavaScript to gather the necessary information from the user's browser - for this part see http://www.onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/\n\nWhen you have this information you can setup UserTimeZone (btw this should NOT be an int as there are timezones with fractions of hours!) to accomodate the current timezone including DST...",
2011-09-12T06:17:07
ScottTx :

The correct answer is what everyone has told you to do - use the TimeZone APIs in the framework. But prior to .NET 3.5 the TimeZoneInfo APIs didnt exist. If you really don't want to use the APIS, or you are using something prior to .NET 3.5, you can find all the timezone info in the registry at \n\nHKLM/Software/Microsoft/Windows NT/CurrentVersion/Timezones\n\nThere are a set of classes available at http://www.michaelbrumm.com/simpletimezone.html that read the registry data directly and do all the timezone calculations required - with adjustments for DST. It's good code (we've used it reliably for years) with source, so you can see what they are actually doing.",
2011-09-20T21:41:45
Charles Lambert :

I would recommend adding a timezone to the users settings and storing that. Timezones have different times depending on the time of year. you can provide a list of time zones for the user to choose from by using the TimeZoneInfo.GetSystemTimeZones method. You can store any date as UTC and convert it (with the TimeZoneInfo.ConvertTime method) to the users time when displaying, and convert it back to UTC when saving it. This will allow the user to change their timezone at any time without causing problems. If you follow this format you should not run into any problems. \n\nBe forewarned, if you do not store the dates as UTC and convert as suggested above you may run into problems. In some time zones certain times do not exist on certain days when changing from daylight savings time to standard time. The TimeZoneInfo class does not play nice with these non-existent times.",
2011-09-22T03:22:21
Matt Johnson-Pint :

The accepted answer doesn't consider that there are time zones that have DST spring-forward transitions right at midnight, and thus the start of the day might not be 00:00 but rather 01:00. Iran, Cuba, and Brazil (some parts) are good examples.\nAdditionally, some time zones may have fall-back transitions that give two possible point in time that are midnight.\nConsider the following function, which accommodates both scenarios:\nusing System.Linq;\n\nstatic DateTimeOffset GetStartOfDay(DateTime dt, TimeZoneInfo tz)\n{\n // Work in the time zone provided\n if (dt.Kind != DateTimeKind.Unspecified)\n {\n dt = TimeZoneInfo.ConvertTime(dt, tz);\n }\n\n // Start with assuming midnight\n var d = dt.Date;\n\n // Check for the time being invalid and handle if so\n if (tz.IsInvalidTime(d))\n {\n // the gap is *usually* 1hr, but not always, so calculate it\n var gap = tz.GetUtcOffset(dt.AddDays(1)) - tz.GetUtcOffset(dt.AddDays(-1));\n\n // advance forward by the amount of the gap\n d = d.Add(gap);\n }\n\n // Also check for the time being ambiguous, such as in a fall-back transition.\n // We want the *first* occurrence, which will have a *larger* offset\n var offset = tz.IsAmbiguousTime(d)\n ? tz.GetAmbiguousTimeOffsets(d).OrderByDescending(x => x).First()\n : tz.GetUtcOffset(d);\n\n // Now we know when the date starts precisely\n return new DateTimeOffset(d, offset);\n}\n",
2018-04-23T19:34:57
yy