I'm doing a planning tool for users around the world. A feature is that something has to be ready at a user-specified time of day. I imagine this being a TimeSpan. For argument sake let's say 8 AM.
The answer seems easy at first
DateTimeOffset.Now.Today.AddDays(1).Add(TimeSpan.FromHours(8)) but that will not generate the right answer.
First thing is that 8 AM could be today and not tomorrow. Let's say the time is now 3 AM. 8 AM is just 5 hours away and not 29 hours away. Easily solved, but it gets harder from here...
2nd thing that provides a challenge is the user's timezone. Let's say the user is located at 55.692756, 12.599010 (The Little Mermaid in Copenhagen, Denmark). How is the position translated into timezone info and applied correctly?
3rd thing is daylight savings time. We might have to add or subtract 1 hour.
I'm asking because I haven't found an elegant way to express this in C#.
Here is what I've come up with so far. I'm using the following nuget packages:
var readyBy = TimeSpan.FromHours(8); // Convert user position into time zone var userIanaTimeZone = TimeZoneLookup.GetTimeZone(55.692756, 12.599010).Result; var userWindowsTimeZone = TZConvert.IanaToWindows(userIanaTimeZone); var userTimeZone = TimeZoneInfo.FindSystemTimeZoneById(userWindowsTimeZone); // Get the local time for the user var userNow = DateTimeOffset.UtcNow.ToOffset(userTimeZone.BaseUtcOffset); // Get the local date for the user var userNowDate = userNow - userNow.TimeOfDay; // Get ready at 8 AM today or tomorrow - whatever comes first var readyAt = userNow < userNowDate + readyBy ? userNowDate + readyBy : userNowDate.AddDays(1) + readyBy; // Possible ajustment to daylight saving time var daylightSavingTimeAjustment = userTimeZone.GetUtcOffset(readyAt) - userTimeZone.GetUtcOffset(userNow); readyAt = (readyAt + daylightSavingTimeAjustment).ToOffset(readyAt.Offset + daylightSavingTimeAjustment);
Let me know if it is 👍 or 👎 or possible improvements/bugs