I'm assuming you're in the UK (where we spent the winter on UTC, but switch to UTC+1 in the summer). Therefore at midnight on 1/1/1970 we're on UTC.
new DateTime(1970, 1, 1).ToLocalTime()
does nothing, except changes Kind
to Local, because DateTime assumes that we specified a point in time in UTC. We then add 10,000 hours, which brings us to a point in winter time.
new DateTime(1970, 1, 1).AddHours(10,000)
also brings us to a point in winter time UTC, so .ToLocalTime()
again does nothing, except change Kind to Local.
However, things get different when we add 100,000 hours, since that brings us to a point after daylight savings kicks in.
new DateTime(1970, 1, 1).ToLocalTime().AddHours(100000)
changes Kind
to Local as before, and then adds 100,000 hours's worth of ticks. There's no appreciation that we moved from UTC to UTC+1.
new DateTime(1970, 1, 1).AddHours(100000)
however brings us to a point in time where local time and UTC differ, because we're after the 29th March 1981 and daylight savings has kicked in. .ToLocalTime()
therefore spots that there's a 1-hour difference and adds it, resulting in a time which is 1 hour ahead.
It's worth remember how DateTime
behaves. It represents an instant in time - a number of ticks since an epoch. It also has a Kind
property, which says whether that time is based on local time, UTC, or is "Unspecified" (i.e. you haven't told it).
For example, new DateTime(1980, 4, 1, 0, 0, 0, DateTimeKind.Local)
(I chose a date after DST), and new DateTime(1980, 4, 1, 0, 0, 0, DateTimeKind.Utc)
have the same value for their Ticks
property, and they print the same string. However, calling .ToLocalTime()
does different things: in the first case it does nothing (because the DateTime
is already in local time), but in the second it adds an hour's worth of ticks to the DateTime
.
So remember, always keep track of what Kind
is, and be aware of the effect that it has when converting between UTC/local time. DateTime
itself isn't particularly smart, but the timezone conversion methods do have a lot of special-case logic around Kind
which can throw you.
I'd argue that you should probably be using DateTimeOffset
instead of DateTime
- that shows you what timezone you're currently in, and does away with the woolly notions of "Unspecified" and "Whatever timezone my PC is in". Try repeating this experiment with DateTimeOffsets
.