4

The following code returns 9.25 when I feel it should return 8.25, what have I misunderstood?

(new DateTimeOffset(2014,09,04,08,15,00,new TimeSpan(0,0,0))).Subtract(new DateTimeOffset(2014,09,04,08,15,00,new TimeSpan(0,0,0)).Date).TotalHours

more simply shown as:-

DateTimeOffset start = new DateTimeOffset(2014,09,04,08,15,00,new TimeSpan(0,0,0));
double result = start.Subtract(start.Date).TotalHours

When run on a Windows 7 PC in Time Zone GMT (adjust for Daylight Saving time) on:-

12th September result = 9.25

12th December result = 8.25

gunr2171
  • 16,104
  • 25
  • 61
  • 88
Old fart
  • 590
  • 1
  • 4
  • 12

1 Answers1

10

The problem is that the DateTimeOffset.Date property returns a DateTime with a Kind of unspecified. That's then assumed to be system-local when you subtract it from the DateTimeOffset.

You can fix this by asking for the UtcDateTime and get the Date from that:

double result = start.Subtract(start.UtcDateTime.Date).TotalHours

Of course, that's assuming that the Date that you want is the date on which the UTC date/time falls. We don't know much about your actual requirements. You might want to consider using my Noda Time library to avoid this sort of ambiguity though - with more types to choose from, it allows you to specify your intentions more clearly.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thank you, driving me crazy for some time, as Development and production are in different time zones. – Old fart Sep 12 '14 at 13:47
  • I have read up on Noda Time several times in the last year - this is possibly the right time to ask about compatibility to SQL server DateTimeOffset(7) via Entity Framework 5 DateTimeOffset types. Will I be converting to / from DateTimeOffsets all the time, thus relying on creating a pattern for evolution of the C# code rather than being able to embed the intentions of my design into the POCO objects? – Old fart Sep 12 '14 at 14:38
  • @Oldfart: I'm afraid EF doesn't support the use of custom types directly. But you shouldn't need to do it "all the time" - typically you just create a "buddy property" I believe (I'm not an EF person myself). See http://stackoverflow.com/questions/25143549 - then most of your code can just use Noda Time, and it'll convert from `OffsetDateTime` to `DateTimeOffset` for persistence. – Jon Skeet Sep 12 '14 at 14:39