5
\$\begingroup\$

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:

  • GeoTimeZone
  • TimeZoneConverter
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

\$\endgroup\$
5
  • \$\begingroup\$ Guessing that location is not a right way to get a Localtime offset because you're not always have access to obtain the coords. Other thing, I'm as user is traveling accross the Globe and want to keep OS in my home Localtime. I can set it in OS settings and it will no has effect on your application. Use OS or Browser's Localtime by default and (optional) allow user to change Time Zone in the profile settings. The target of this suggestion is the same as the most of other software behavior. \$\endgroup\$
    – aepot
    Nov 12, 2020 at 22:15
  • \$\begingroup\$ Thank you for your feedback @aepot. I have the correct coordinates of the user as it is a gps tracker in a vehicle \$\endgroup\$
    – Tim Skauge
    Nov 12, 2020 at 22:38
  • \$\begingroup\$ Doesn't nodatime.org solve this? \$\endgroup\$
    – BCdotWEB
    Nov 13, 2020 at 7:30
  • \$\begingroup\$ @BCdotWEB possibly 🤔 could you give a link to where such an example is shown? \$\endgroup\$
    – Tim Skauge
    Nov 13, 2020 at 9:31
  • \$\begingroup\$ You can acchieve the same with var userNowDate = userNow.Date; assuming you want only a date (at 00:00:00). \$\endgroup\$
    – Iztoksson
    Nov 15, 2020 at 19:15

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.