views:

530

answers:

5

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?

A: 

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.

Visage
+2  A: 

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).

Saint Gerbil
Indeed. The answer is "who's DST"?
tpdi
Indeed. The answer is "whose DST?"
tpdi
+2  A: 

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

Orion Edwards
No, that is NOT a valid workaround. See my post. To PROPERLY store a local time suitable for conversion to a UTC time, you must specify ALL applied offsets from UTC (which includes the time-zone AND whether DST was in effect). Since DateTime never inputs whether DST was active for a given local time, every local time value is inherently incomplete/flawed and is therefore not suitable for conversion. Windows even screws up the conversion from UTC to Local, since it seems to apply the DST offset based on whether it's in effect at method-call time rather than at the given time, which is asinine.
Triynko
You said "conversions to UTC will take into account daylight savings", but that's impossible, because the DateTime constructor never asks you whether DST was in effect, so it cannot possibly know whether it was in effect between the hours of 1 and 2am on Nov. 2nd (in the U.S. anyway). It also would have problems converting that non-existent local hour that DateTime allows you to store that we skip over when we set the clocks ahead.
Triynko
It's actually rather funny. ToUniversalTime will work for all but 2 hours on 2 days out of the entire year. Meanwhile, the corresponding ToLocalTime (and underlying APIs) causes Windows to display an incorrect file-modification times for 5 to 7 months!!! out of the year, depending on whether or not the file was modified during a date range where its DST "mode" (active or inactive) matches that of the current date. What a bug.
Triynko
To test this, put a file on your desktop and don't modify it for a year. WRITE DOWN the modification date. For 5 to 7 months out of the year, the date you wrote down will not match the date Windows Explorer displays. Lol.
Triynko
+1  A: 

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.

Triynko
+2  A: 

.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.

Ian Boyd