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.