As a Microsoft employee with significant involvement with Windows time zone data, please allow me to assure you that Microsoft works very hard to ensure that it releases updates to keep Windows time zone data as accurate as it possibly can be.
There are several challenges, including the timing of time zone changes as given by governments. For example, we recently posted a notice about upcoming Windows time zone changes for Fiji, Cyprus, Sudan, Tonga, Namibia, and Turks & Caicos. In some cases, we can meet the effective-dates established by these different governments. In some cases we cannot because they don't offer enough lead time.
Consider the recent case of Sudan, who told the the IANA tz mailing list on October 17th, 2017 of a change effective November 1st 2017. IANA has processed this change, and so has Microsoft. But due to the short notice, and the time it takes to process such a change in the Windows operating system, it will be a little while before there is a new "Sudan Standard Time"
time zone created in the Windows time zone data. Thus, we issue interim guidance to use a different time zone for the time being, then switch back once we have data that properly reflects the full history of time in the affected region.
With regard to the Windows time zone you mentioned, "E. South America Standard Time"
, the time zone data is correct. If you expand the registry entry, you'll see that there is a sub-key called "Dynamic DST" which contains the year-by-year changes to the data. For some time zones, this isn't necessary at all, and for other time zones you'll find a very small amount of data because the same rule repeats year after year. But in the case of Brazil, you'll notice Dynamic DST entries for 2009 through 2040.
(click the image to see the full resolution, and note the areas I manually marked in red that change year-over-year)
The Dynamic DST entries support the Win32 DYNAMIC_TIME_ZONE_INFORMATION
structure, and corresponding APIs with "dynamic" in their name, such as GetDynamicTimeZoneInformation
. (They also support the System.TimeZoneInfo
class in the .NET Framework.) Most of these APIs have been in places since Windows Vista / Server 2008, with some others coming in Windows 7 / Server 2012.
Note that the TZI
entry that is in the parent key is copied in from the current year's dynamic rule by internal Windows processes. This supports the APIs that work with Win32 TIME_ZONE_INFORMATION
structures, which have been in place since Windows 2000.
To answer the specific questions you asked:
Have I understood the recurrence rule correctly?
The specific rule you cited is for 2017 only, and it says that DST ends on the 2nd month (February), on the 3rd Saturday, at 23:59:59.999 local time, and starts again on the 10th month (October), on the 2nd Saturday, at 23:59:59.999 local time. Keep in mind that Brazil is in the southern hemisphere, so DST starts late in the year and ends early in the next year.
Also, you may wonder why it's 23:59:59.999 on Saturday instead of 00:00:00.000 on Sunday. This is an artifact of history. There have in the past been certain programs and processes that incorrectly used <=
instead of <
to evaluate the transition, and thus would accidently move the clock one millisecond into the next day, back out of it, then back into it again. The events generated by the day changing erroneously could then lead to further problems. Microsoft has done their best to fix those bugs, but still opts to be 1ms off instead of risk the problem popping up in some new place one day. (This only applies for transitions that occur exactly at midnight.)
Is there known issues about several timezone, especially the "E. South America Standard Time" one?
There are no known issues for that time zone, however there is a known issue that Windows time zones (even with the dynamic DST data) can only support a maximum of two time zone transitions in a single year. So, in places like Morocco that transition four times per year there are some internal workarounds in place that keep the current time zone data in sync such that "now" is an accurate representation of local time, but cannot represent all points of the year correctly at any given time.
We also don't currently have a time zone that maps cleanly for Troll Station, Antarctica. The reason is that from 2005 to 2015, this research station (population under 50) transitioned through three different offsets (UTC+0, UTC+1, and UTC+2) every year.
If your application is critically dependent on either of the above scenarios, then I recommend using an API with IANA data sources instead of the Win32 APIs.
Is there a reason why a DST start date, that obviously occurs regularly every year, on the 3rd week of the 10th month, have a value set on the 2nd week?
Yes, as mentioned above, it's due to the 1ms intentional error. DST in 2017, in the parts of Brazil that have DST, starts on Sunday October 15th at 00:00:00.000. That's the third Sunday of the month. 1ms prior is 23:59:59.999 on Saturday October 14th, which is the second Saturday of the month. This can be different every year, which is why there is Dynamic DST data.
Are timezone written in Windows registry reliable, if not, which function of the Windows API should I use to convert a timezone with DST from a date written in a different timezone than the one set on the local machine?
If you are using the Win32 APIs, they use the registry data themselves, so there is no need to work with the registry data directly. You should prefer the "Dynamic" versions of the APIs, as they properly account for the year-over-year changes in the Dynamic DST data. Sometimes these are labeled as "Ex". For example, the function you asked about is best handled by the TzSpecificLocalTimeToSystemTimeEx
function.
...
That all said, if you are able to avoid using Windows time zone data in your application, I recommend doing so. Prefer IANA data sources, or those derived from them. There are many routes to working with IANA time zone data. Newer Windows APIs like Windows.Globalization.Calendar
and Windows.Globalization.DatetimeFormatting.DateTimeFormatter
in WinRT/UWP do indeed use IANA time zones, and that is clearly the path forward. In the standard C++ space, I highly recommend using Howard Hinnant's date/tz libraries, or those provided by the ICU project. There are several other viable choices as well.