Is DateTimeOffset.UtcNow.DateTime equivalent to DateTime.UtcNow?
Asked Answered
H

3

23

I need to upgrade some piece of code from statically calling DateTime.UtcNow to calling a time provider service which returns, basically, DateTimeOffset.UtcNow. To further convert this DateTimeOffset instance to DateTime, there is the DateTime property. Alternatively, it seems that there is an implicit conversion from DateTimeOffset to DateTime.

I'm a bit concerned that there might be some edge cases that I can't see right now where these two would not be equivalent. Are there?

Holloway answered 11/11, 2015 at 16:34 Comment(1)
"To further convert this DateTimeOffset instance to DateTime, there is the DateTime property" - there is also the UtcDateTime property, which seems more appropriate for your scenarioUndersize
S
17

If you look at the value of DateTimeOffset.UtcNow.DateTime.Kind you will see the it is Unspecified. Unspecified kinds are treated as local times by the framework. The kind of DateTime.UtcNow is Utc, so there will be differences when timezone conversions are applied to and from the local timezone.

The work around is to use the DateTimeOffset.UtcNow.UtcDateTime which has the Utc kind specified.

Soredium answered 11/11, 2015 at 18:4 Comment(1)
DateTimeOffset.UtcNow is not UTC? Why is the naming of property so confusing?Stockton
F
4

Internally it looks like this:

  public static DateTimeOffset UtcNow {
        get { 
            return new DateTimeOffset(DateTime.UtcNow);
        } 
  } 

  public DateTime DateTime { 
        get {
            return ClockDateTime;
        }
    } 
   private DateTime ClockDateTime { 
        get {
            return new DateTime((m_dateTime + Offset).Ticks, DateTimeKind.Unspecified); 
        }
    }

  public DateTime UtcDateTime { 
        [Pure] 
        get {
            Contract.Ensures(Contract.Result<DateTime>().Kind == DateTimeKind.Utc); 
            return DateTime.SpecifyKind(m_dateTime, DateTimeKind.Utc);
        }
    }

So it looks like you could end up getting a DateTime that was based on UTC but then gets converted to Unspecified.

Fianna answered 11/11, 2015 at 16:42 Comment(6)
In which case calling DateTime.SpecifyKind on the result should be enough to make it entirely identical to DateTime.UtcNow, right?Wooley
Would seem correct, however wouldn't that make it the third DateTime object to be created? UTCNow, ClockDateTime and then finally the kind adjusted. If the OP is happy to convert then yes that could be ok. If it's some existing code that is relying on them being 100% equivalent then there may be problems.Fianna
Could I use .UtcDateTime instead of .DateTime property on the DateTimeOffset instance? Like so: DateTimeOffset.UtcNow.UtcDateTimeCatechol
DateTime is a value type, no object creation is involved (at least not in the way I think you mean) either way.Wooley
See edit and have a wander around referencesource.microsoft.com/#mscorlib/system/…Fianna
@hvd totally true, I guess I automatically frown when I see lots of conversions of the same type back and forth being done :)Fianna
N
1

From the .NET reference source:

public static DateTimeOffset UtcNow {
    get {
        return new DateTimeOffset(DateTime.UtcNow);
    }
}

So, yes, it looks like it's equivalent to DateTime.UtcNow.

Nesta answered 11/11, 2015 at 16:42 Comment(1)
It seems to get further mangled a bit later on, so I think you're right they may have the same value but not sure about the DateTimeKind setting.Fianna

© 2022 - 2024 — McMap. All rights reserved.