I have two DateTime
variables. Each has a timezone stored in the variable so that when I ToString
with format including zzz I get a string including +01:00
.
At design time I do not know what the timezones will be and I am expecting the variables to have different timezones from each other.
I want to compare the two DateTime
values so that I know which is more recent.
For example, if variable A is 2015-07-04T02:00:00+03:00
and variable B is 2015-07-03T18:00:00-07:00
then B > A.
What do I write in C# to tell me this? (I would prefer not to use a third party library.)
(To the SO question-closing zealots: I have spent several hours investigating this using Google, MSDN and SO and am confused. I cannot find a very similar question to this on SO. I am confident that answers to this question will help others.)
Did you try this?
You said:
This is a common misunderstanding.
DateTime
doesn't have a time zone stored in the variable. It only has aKind
property, which is of typeDateTimeKind
, and can be eitherUtc
,Local
, orUnspecified
.When calling
ToString
, thezzz
format specifier uses theKind
property to determine which offset to display.When the
Kind
isDateTimeKind.Utc
, the offset is always+00:00
.When the
Kind
isDateTimeKind.Local
, the offset is determined from the local time zone on the computer where the code is executing. For example, my computer is set to US Pacific time, so the offset will be either-08:00
or-07:00
depending on whether daylight saving time is in effect or not.When the
Kind
isDateTimeKind.Unspecified
, the behavior is the same as if it wereLocal
. Keep in mind that other methods treatUnspecified
in different ways - this is just the particular behavior of thezzz
specifier.MSDN actually says:
Going back to your question:
Then you cannot use
DateTime
. You should instead useDateTimeOffset
, as it retains a specific time zone offset instead of using aDateTimeKind
.See also: DateTime vs DatetimeOffset
Furthermore
As Gustav pointed out, you can use just
DateTime
, as long as you convert back to universal time before comparing. This works due toDateTime
's hidden fourth state (more here). The state is set properly during parsing, and is taken into account whenToUniversalTime
is called. Then comparison has valid UTC times to operate from.And the result:
If your local time zone is set to Pacific Time, you'll get the above results. However, if it's set to something else - it's possible you will get
True
for the last result, because the values may have been parsed to different local times in your time zone, even though they'd be the same local time in the Pacific time zone.Using
DateTimeOffset
is still simpler, going through less conversions, and not being affected by the local time zone.