Tutorial :DateTime difference operator considers daylight saving?



Question:

As far as I know the difference operator of the DateTime type considers leap years: so

new DateTime(2008, 3, 1) - new DateTime(2008, 2, 1) // should return 29 days  new DateTime(2009, 3, 1) - new DateTime(2009, 2, 1) // should return 28 days  

But what about daylight saving?


Solution:1

I don't think it will. The documentation simply says that a DateTime is stored as the number of ticks since 12:00:00 midnight, January 1, 0001, but it doesn't say in which TimeZone the midnight actually is - I would have to assume that if it was always stored internally in UTC, they would say so.

You can easily get around this though: Just do:

var difference = Dt1.ToUniversalTime() - Dt2. ToUniversalTime()  

and the conversions to UTC will take into account daylight savings


Solution:2

.NET does not handle daylight savings time correctly, even though it gives answers you want. You want incorrect answers.

Short version:

  • How can .NET know that in 1977 daylight savings time was in effect the entire year, due to the energy crisis?

  • How can .NET know what the daylight savings rules will be in Israel, when the rules are decided year-to-year by the Knesset?

  • How is .NET to know that the US ran on DST year round during WWII, and from 1945 to 1966 the DST rules varied region to region, and the rules still do vary region to region.

.NET tries a cop-out, and uses the current daylight savings rules, even if they weren't, or will be, in effect. The result is that you get answers which, while are what you think you want, are incorrect.

From Raymond Chen's blog entry, Why Daylight Savings Time is nonintuitive:

Why don't the (win32) time zone conversion functions use the time zone appropriate for the time of year?

...

Win32 does not attempt to guess which time zone rules were in effect at that other time. So Win32 says, "Thursday, October 17, 2002 8:45:38 AM PST".

Note: Pacific Standard Time. Even though October 17 was during Pacific Daylight Time, Win32 displays the time as standard time because that's what time it is now.

.NET says, "Well, if the rules in effect now were also in effect on October 17, 2003, then that would be daylight time" so it displays "Thursday, October 17, 2003, 9:45 AM PDT" - daylight time.

So the answers you get are wrong. But since you expect the wrong answer, it's what you get.


Solution:3

Daylight saving time is more specific than the general 12 timezones and which countries used them.

Different countries or groups of countries use different dates for when DST happens.

its a bit of a pain really not to mention the countries which dont do it, or parts of countries.

For example Queensland, AU doenst have DST inspite the rest of the country does.

I would not be surprised if it does not, in the event that it does it would be unable to do it with out a cultureinfo 9at the least).


Solution:4

It won't and it in fact CANNOT, based on the fact that it does not either force you to use UTC to construct a DateTime nor does it allow you to specify whether DST was in effect when you construct a DateTime with a local time value. Furthermore, it allows the mode (LT or UTC) to be "unspecified", which is just asinine.

By allowing the construction of DateTime values from Local Time values, it's possible to construct a DateTime value (specified as Local Time) which is ambiguous (for example any time between 1 and 2am on November 2nd in the U.S., when the local hour repeats itself) and cannot be deterministically converted back to UTC, UNLESS the constructor provided a parameter for specifying whether DST was in affect for the given local time.

Since it provides no such parameter, the design of the DateTime class is incomplete and flawed, having failed to consider all the parameters necessary to properly specify a local time correctly.

I think that's why they created the DateTimeOffset class, which... if you were confused why such a seemingly redundant class exists... that's why.

As a result, you should never do any kind of calculation with any DateTime instance that is not set to DateTimeMode.Utc. Only use UTC. You actually can't convert either to or from LT, because it's BUSTED by two different bugs, both ways. 1. Going from LT to UTC is busted because, as mentioned, it doesn't allow you to specify whether DST was in effect for that one ambiguous hour in LT. Oh, it also allows you to specify a local hour that's basically impossible, such as the hour we skip over when the clocks are set ahead. 2. When converting a UTC value in the past to a local time, Windows screws that up by offsetting for DST based on whether it's in effect NOW, rather that the given time, which is seriously asinine. Of course, you may have noticed this problem when a modification time you wrote down, stored, or used in the name of a file, one day shows up an HOUR OFF in Windows explorer. No, you're not crazy, Windows just has a serious bug in it, which they never found the time to fix somewhere between the release of DOS and the latest .NET framework (~2 decades)! Of course, that bug affects CVS systems and anything that tracks modification times. The FAT file system stores times as local times, which means that it's just completely screwed.


Solution:5

Test it and see!

Its just as easy to write a test as you have done for the DST case as it is for the leap year case.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »