Reputation: 6907
I'm trying to replicate the Windows Date & Time settings in a UWP application, and I'm having a bad time dealing with Daylight Saving Time (DST) settings.
I managed to get everything working, I can change the system time and timezone just fine from my app, but the option Adjust for daylight saving time automatically is confusing me.
At first I thought it was enough to check TimeZoneInfo.SupportsDaylightSavingTime
, then I found out that I probably also need to check if the currently selected date/time is in DST range by doing TimeZoneInfo.IsDaylightSavingTime
.
Well, I thought I had it right, but after testing, my own "Adjust DST" option is not the same as the Windows setting, and since I can't see the Windows source code, I have no idea what other conditions they are checking to disable/enable it.
My UWP application:
Windows settings:
Am I still missing something here? My other question regarding this can be found here for those who are interested.
Maybe some MS devs with insider information can tell me the logic behind this toggle switch :-)
Thank you in advance!
UPDATE:
Results from tzutil show that when date is 16th May, 2011 and timezone is Moscow (UTC+3), turning off DST by using the command tzutil /s "Russian Standard Time_dstoff"
simply returns "Russian Standard Time" without _dstoff because DST is not applicable, and that lines up with what Windows reports.
But, then why does .NET's TimeZoneInfo class say this? Tried also with:
var currentDateTime = new DateTime(2011, 5, 16, 0, 0, 0, DateTimeKind.Local);
var isDst = TimeZoneInfo.Local.IsDaylightSavingTime(currentDateTime); //True
So, .NET says the current date is in DST range, but DST cannot be turned off using TZUTIL nor from Windows settings?
Maybe I'm missing something very obvious here, but I don't see it...
UPDATE:
Changing month to February, turns Adjust DST toggle on in Windows, due to adjustment rules? But, in Helsinki, we also have these transitions, and the toggle isn't disabled? What's different?
UPDATE:
Decided not to do any of this, and just check TimeZoneInfo.SupportsDaylightSavingTime
. It's not worth anyone's time or energy to do it exactly like Windows does.
Upvotes: 2
Views: 6434
Reputation: 241420
A few things to address your questions:
Don't use the System.TimeZone
class at all - ever. It has lots of problems, and there are better alternatives. For most .NET code, use System.TimeZoneInfo
instead. Since you said you are writing a UWP application, you might also benefit from Windows.Globalization.Calendar
and Windows.Globalization.DateTimeFormatting.DateTimeFormatter
classes. Open source libraries such as Noda Time can also be a good choice.
In the first code block you showed, you are using System.TimeZone.IsDaylightSavingTime
. The remarks in the docs explain the results you are seeing:
"Because the
TimeZone
class supports a single daylight saving time adjustment rule, theIsDaylightSavingTime(DateTime)
method applies the current adjustment rule to any date, regardless of whether the adjustment rule was in effect on that date. Assuming that the operating system itself has accurate historic daylight saving time data, a more accurate result is available by using theTimeZoneInfo.IsDaylightSavingTime
method. Whenever possible, use theTimeZoneInfo.IsDaylightSavingTime
method."
In the second code block you showed, you are correctly using System.TimeZoneInfo.IsDaylightSavingTime
and are getting True
when you expected False
. Though this is confusing, and arguably incorrect, it is explainable:
TIME_ZONE_INFORMATION
, DYNAMIC_TIME_ZONE_INFORMATION
, and more specifically, REG_TZI_FORMAT
) do not support a change in standard offset in the middle of a calendar year. They were designed without this sort of change in mind - a very long time ago.System.TimeZoneInfo.IsDaylightSavingTime
).As far as I can tell, Windows does indeed look to this data to determine whether to show the option or not. If there is a transition in the current calendar year (as determined by the system clock), then the option will be presented - regardless of if this transition was related to DST or due to some other reason.
Additionally, some general advice:
Most applications should not be trying to change the system time, time zone, or DST settings. Though indeed there are ways to do this, it can have drastic consequences. These are system-wide global settings, which will effect everything on the computer - not just your application.
In particular, changing the time too drastically can impact the ability to authenticate correctly with other systems. For example, Windows Authentication (Active Directory, SSPI, etc.) uses Kerberos - which has a 5-minute tolerance from UTC. Additionally, accessing web sites that use security certificates (HTTPS, SSL, TLS, etc.) can fail if the certificate is expired or has not yet been issued, according to the system clock. Thus, the safest path to success is to set time automatically, and not allow the user to deviate.
While changing the time zone and/or DST settings doesn't affect auth, it is still a global setting. Anywhere on the machine that is working with local time will pick up on this setting - not just your application.
If you are indeed going to be changing the time zone, keep in mind you may need to clear the local time zone cache to pick up on the new setting in your application. See this question and answer for more details.
If your intent was just to change the time zone for your application, then just keep track of the TimeZoneInfo.Id
of the selected time zone and apply it through TimeZoneInfo.ConvertTime
and related methods where needed.
You probably do not need to have a setting to disable automatic DST adjustment. The existence of this setting existing in Windows at all, is a legacy artifact from the original implementation of the time zone settings from the early days WinNT and Win9x. Most users should leave it on.
Turning it off has only one legitimate use case these days, which is when a government announces a change in time zone from one that had DST to one that doesn't have DST (or has "permanent DST") and there is no other existing time zone entry that has the same base offset without DST and when said government does not provide enough time for Microsoft to create and distribute a new time zone entry for the affected region before the change goes into effect. Such things do happen, but are rare. IMHO, It would be reasonable for this setting to disappear at some point in the future. (Just my personal opinion, not speaking for Microsoft on this.)
Upvotes: 4