Given a DateTimeOffset
, there is never any confusion about what point in time that represents. So they are always reliable.
But there are some cases where a DateTimeOffset
alone is still not sufficient. Here's an example of a common situation:
- You are in New York, USA on March 10th 2013.
- You find out about an event happening at 1:00 AM local time.
- You record it as a
DateTimeOffset
with the value 2013-03-10T01:00:00-05:00
.
- Later, you find out that you were given incorrect information, the event actually occurred at 3:00 AM.
- So you go to edit, and you change the value to
2013-03-10T03:00:00-05:00
.
- But this would be incorrect. On that particular day, daylight saving time starts, and so 3:00 AM is only one hour later than 1:00 AM. If you just advance the time, without considering that the offset may have changed, then you am referencing the wrong point in time.
- It should have been
2013-03-10T03:00:00-04:00
.
To overcome this situation, you must also know that the time was recorded in New York. You knew that in the first step, but then it was thrown out when you recorded it. Somewhere else in your application, you must hold on to this fact. Preferably, you would keep a time zone id, so that you could re-calculate the correct offset.
If using the TimeZoneInfo
class in your application, then you would want to track the value of the .Id
property, along with your DateTimeOffset
. For New York, the time zone id would be "Eastern Standard Time"
. This is a bit confusing, because this same value is used regardless of whether DST is in effect or not. (There is no Windows time zone with an Id
of "Eastern Daylight Time"
). Also, there is no built-in class or struct that will pair a TimeZoneInfo
with a DateTimeOffset
. You have to do it yourself.
If you are using Noda Time (which I highly recommend). Then you can take advantage of the IANA time zone id of "America/New_York"
, and the ZonedDateTime
object - which is designed for this exact situation.
You should also refer to DateTime vs DateTimeOffset. You should find the analogy there quite useful.
There are also some cases where DateTimeOffset
is not appropriate. Maybe this one is obvious, but it's still worth mentioning.
- When you are not refering to a single moment in time, but a relative point on the calendar.
This happens more often than you would think. For example:
- In the United States, this year daylight saving time began on March 10th 2013 at 2:00 AM.
- But it didn't happen at at the exact same moment. Each time zone has their own local 2:00 AM, so there are actually several different transition points on the instantaneous timeline.
- (Aside, but worth mentioning, in Europe, DST ("Summer Time") happens all at once. The transition is based on the same UTC moment for Western, Central, and Eastern European time.)
There are other real-world examples where the same point on the calendar is not the same point in time, yet people tend to think of them as if they were.
- Day boundaries ("today", "yesterday", "tomorrow")
- Other whole named days ("this Wednesday", "last Friday")
- Television Shows ("7PM Tuesday nights")
- Telephone Calling Plans ("Free nights and weekends")
- Countless others...
In Noda Time, you would use a LocalDateTime
for these scenarios. Without Noda Time, you would use a DateTime
with .Kind == Unspecified
.