2

I am using function GetUtcoffset() in TimeZoneInfo object to get the Utc offset value for a particular date time. Generally, daylight saving would follow a particular rule such as "begins on the first Sunday in October,and ends on the first Sunday in April" (AUS Eastern Standard Time), so I would trust the result that the function produces.

But I do wonder what would happen to the result if the daylight saving is delayed or varied by government's decision? In the past, there has been a few occasions that (Australian) government has broken the rules of daylight saving for certain events. In these occasions, would calling GetUtcoffset() produce incorrect result or the library is smart enough to "occasionally" fetch daylight saving updates from some source in the internet?

Usage: I am devleping a parking management system. One database is shared across multiple clients whose timezone are different. Parking event time can be used as evidence in court so it is extremely important that we get it right. When the system receive a notification that a vehicle has parked, the system will generate the arrival time. Given that the notification could have come from a remote site in a dfiferent time zone, I'd like to know if I can reliably use the time zone to workout the current date time at the client site.

Example:

string clientTimeZoneId = "AUS Eastern Standard Time";
var utcTime = DateTime.UtcNow;
var clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById(clientTimeZoneId);
var arrivalTime = utcTime.Add(clientTimeZone.GetUtcOffset(utcTime));

This is where the GetUtcOffset function becomes important. Given that in year 2019-2020 "AUS Eastern Standard Time" daylight saving ends on 5 April 2020, calling GetUtcOffset on the 6th would give +10:00:00. However, if for any reason (Olympic events for exanmple), DST is extended to 10th, the arrivalTime could potentially be one hour incorrect depending on the value of GetUtcOffset.

At the moment, our system administrator has to update daylight saving date in our database manually each year, but it would be nice not having to do so. I don't know exactly what the government did in these events, but they must have sent the updates somewhere otherwise all computers in the affected time zone will have incorrect time. Hence, back to my original question, would the TimeZoneInfo be fetching data from any "DST source"?

Viet Nguyen
  • 406
  • 3
  • 12
  • 1
    With time, there is probably always some case where common wisdom breaks down. You don't state your actual use, so I'll just leave this: https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/ – Austin T French Nov 06 '19 at 02:52
  • @AustinTFrench, Thanks for the link. I love Jonskeet's blog. Why I am trying to understand the blog information, I updated the question with what I am planning to do with GetUtcOffset. – Viet Nguyen Nov 06 '19 at 04:03
  • 2
    I'm not sure the mechanism but microsoft publishes changes to their tz database here https://blogs.technet.microsoft.com/dst2007/ and I believe they're applied via windows update. Another option is to use the IANA database (https://www.iana.org/time-zones) and download the tzinfo yourself - at least then you're in control of updates and can log what you were using at the time on a machine by machine basis – David Waterworth Nov 06 '19 at 04:07
  • 1
    Also see https://stackoverflow.com/questions/17348807/how-to-translate-between-windows-and-iana-time-zones – David Waterworth Nov 06 '19 at 04:07

1 Answers1

2

There's two parts to your question. I'll start with the code example you gave first:

var arrivalTime = utcTime.Add(clientTimeZone.GetUtcOffset(utcTime));

This is applying the offset incorrectly. Since utcTime has its Kind property set to DateTimeKind.Utc, so does the resulting value after calling Add. Thus, you aren't adjusting for offset, but actually choosing a different point in time (either 10 or 11 hours in the future).

There's a few different ways you could do it instead:

  • You could use the ConvertTime or ConvertTimeFromUtc methods on TimeZoneInfo. The resulting date and time will be the same as before, but the Kind will be correctly set to DateTimeKind.Unspecified.

      DateTime utcNow = DateTime.UtcNow;
      DateTime arrivalTime = TimeZoneInfo.ConvertTime(utcNow, clientTimeZone);
    
  • You could construct a DateTimeOffset using the offset you retrieved:

      DateTimeOffset utcTime = DateTimeOffset.UtcNow;
      DateTimeOffset arrivalTime = utcTime.ToOffset(clientTimeZone.GetUtcOffset(utcTime));
    
  • You could more easily create a DateTimeOffset using TimeZoneInfo.ConvertTime. This does the same thing as the previous code, but is cleaner.

      DateTimeOffset utcTime = DateTimeOffset.UtcNow;
      DateTimeOffset arrivalTime = TimeZoneInfo.ConvertTime(utcTime, clientTimeZone);
    

For the scenario you described, I'd recommend using DateTimeOffset. You will have both the local time, and the offset from UTC. Store the whole thing. (If you're using something like Microsoft SQL Server for your database, you can simply use a single datetimeoffset field.)

The nice thing about having both the local time and the offset is that even if something were to change, you'd have enough data to recover the actual point in universal time, and you still have data in a format that can be rationalized by the local time. (Alternatively, you could store both the UTC time and the local time in two separate fields. Sometimes that helps for indexing purposes anyway.)

As to your second question about the reliability of the data, I suggest reading this question, and my answer to it. Generally speaking though - yes. The data is reliable. But lets unpack the scenario you described about deviations by the government.

  • First of all, are you aware of any such deviations that have already occurred that are not recorded in the time zone data? Take a look at the history on timeanddate.com, or in the sources of the IANA time zone database. If there are deviations that aren't recorded, they probably should be. Please send such information to the tz discussion list. Everyone else picks up changes from there.

  • For Windows, you can examine the registry data at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\AUS Eastern Standard Time\Dynamic DST. See the Exploring Windows Time Zones... Microsoft blog post by Josh Free to understand how they work. For Sydney, the last change in rules recorded was in 2008, which aligns with IANA and timeanddate information.

  • Keep in mind that Windows assumes the rules for Sydney in 2007 were the same for all points in time before that. It doesn't have the depth of history that the IANA database does. For example, Windows does not know about the deviation for the 2000 Olympics that is called out in the commentary in the IANA database. If such historical changes are important for your application, then you would need to use the TZDB provider in NodaTime. (Though I can't imagine why you would need that history for a present-day parking application.)

So, what happens if the Australian government decides to make a deviation in the future?

  • If they gave enough notice, then both IANA and Windows would pick up the change and distribute it via Windows Update. Your Windows computer would receive the change automatically, and your application would correctly honor the deviation.

  • If they did not provide enough notice, then Microsoft would follow the policy described at aka.ms/time, providing guidance for a workaround and working to get the change out as quickly as practical. IANA would likely rush a change out as well, but distribution times vary depending on implementation (Linux, Java, Python, Android, Noda Time, etc. each distribute time zone data in their own ways.)

Short-notice time zone changes have indeed happened in the past, and are problematic. Fortunately, they have been fewer in recent years. I blogged on this back in 2016. See: On the Timing of Time Zone Changes.

TL;DR:

Hence, back to my original question, would the TimeZoneInfo be fetching data from any "DST source"?

  • For Windows, the source is Microsoft via Windows Updates. If you keep your system up to date, then your application will have the correct time zone data. Such updates are announced on this blog.

  • For .NET running on other platforms (Linux, OSX), the ultimate source is the IANA time zone database, whose data is distributed by the platform you're running. For example, Ubuntu Linux ships a tzdata package with these updates.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575