0

See the title: for the solution I'm working on, I need to get the current timezone offset (from the client, running javascript/jQuery) and use it in backend C# code. The question is rather similar to the one asked here, but there are a few differences - the main one being that I am pretty sure that the time on the client computer won't be tampered with. So new Date().getTimezoneOffset() will do just fine.

I cannot read the value upon submitting a form since the user is not working in a form: after the user has logged in, among the items that are visible on the screen is a table with data entered by the user or by other users. This data contains UTC datetimes that have to be adjusted according to the client's timezone. C# code is responsible for retrieving and formatting the data - hence my question.

What would suffice, is storing the value somewhere so that C# can read it when necessary. But I don't think that can be done as well. What would be the approach here?

Thanks in advance!

Cooz
  • 83
  • 1
  • 2
  • 10
  • Most websites I encounter usually just let you select a timezone in your profile preferences. I suppose you could just make an AJAX POST call to your server with the information and store it with the session data. – itsme86 Aug 03 '20 at 15:22
  • If I understand this right you could do the conversion at client-side using new Date().getTimezoneOffset() as it's just the matter of displaying time in client's timezone – Alwaysa Learner Aug 04 '20 at 06:07
  • @Alwaysa Learner - Yes I can do that, but then: how do I get C# to access this value? – Cooz Aug 04 '20 at 06:40
  • I am still not able to understand why does backend have to know this value. However, if you like to do that only thing I can think of is storing timezone for each user in user table and update this when user signs in from a different time zone. – Alwaysa Learner Aug 04 '20 at 15:59

1 Answers1

2

Your suggested approach is flawed in that the current offset from the client's browser is only going to apply to the current date and time. In reality, time zone offsets change over time within a given time zone. You cannot just take a singular offset from one point in time and expect to use it to convert other dates and times to the same time zone. Instead, you need to use the string that identifies the time zone, not an offset from that zone.

As an example, consider the Eastern time zone in the United States. For part of the year, it uses UTC-5, and we call it Eastern Standard Time (EST). In another other part of the year, it uses UTC-4, and we call it Eastern Daylight Time (EDT). This time zone is identified by either the IANA time zone ID "America/New_York", or the Windows time zone ID "Eastern Standard Time" (which covers the entire zone, both EST and EDT despite its wording).

So, break this problem apart into a few steps:

  1. In JavaScript, identify the users's IANA time zone (America/New_York):

    • If you are targeting modern web browsers, you can call this function:

      Intl.DateTimeFormat().resolvedOptions().timeZone
      
    • If you need to support older web browsers, you can use jsTimeZoneDetect, or moment.tz.guess() from Moment-Timezone.

  2. Send that string to your web server through whatever mechinsm you like (form post, XHR, fetch, etc.)

  3. In your .NET code, receive that string and use it to reference the time zone and do the conversion. You have two options:

    • You can use Noda Time, passing the IANA time zone ID to DateTimeZoneProviders.Tzdb as shown in the example on the home page.

    • You can use .NET's built-in TimeZoneInfo object. If you're running .NET Core on non-Windows systems (Linux, OSX, etc.) you can just pass the IANA time zone ID to TimeZoneInfo.FindSystemTimeZoneById. If you are on Windows, you'll need to first convert it to a Windows time zone ID ("Eastern Standard Time"). You can use TZConvert.GetTimeZoneInfo from my TimeZoneConverter library.

  4. Once you have either a DateTimeZone from Noda Time, or a TimeZoneInfo object, you can use the methods on it to convert UTC values to local time values for that time zone. Each of these will apply the correct offset for the point in time being converted.

I'll also say, many applications simply ask the user to choose their time zone from a dropdown list and save it in a user profile. As long as you're storing a time zone identifier string and not just a numeric offset, this approach is perfectly acceptable to replace steps 1 and 2 above.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • Thanks Matt, I'll go with what you suggest in your last paragraph. – Cooz Aug 06 '20 at 06:30
  • The other option, where possible, is to send the UTC value to the browser and do the conversion there. UTC to local time is much easier, when you don't have to worry about identifying the time zone. – Matt Johnson-Pint Aug 06 '20 at 16:16