Kevin
Kevin

Reputation: 1009

Confusion with the naming of 'LocalDateTime' in NodaTime

I'm confused with the naming of LocalDateTime in NodaTime. Reading the documentation, it appears that it says:

A LocalDateTime value does not represent an instant on the global time line, because it has no associated time zone

Therefore, I would interpret this as:

"If I create a LocalDateTime in daylight savings, it doesn't matter, because this LocalDateTime has no knowledge of TimeZone and therefore no known offset from UTC."

Therefore, if I want to convert that LocalDateTime to UTC, I must do this:

// We can't convert directly to UTC because it doesn't know its own offset from UTC.
var dt = LocalDateTime.FromDateTime(DateTime.SpecifyKind(myDt, DateTimeKind.Unspecified));

// We specify the timezone as Melbourne Time, 
// because we know this time refers to Melbourne time. 
// This will attach a known offset and create a ZonedDateTime.
// Remember that if the system time variable (dt) is in daylight savings, it doesn't
// matter, because LocalDateTime does not contain such information.
// Therefore 8:00 PM in Daylight Savings and 8:00 PM outside of daylight savings
// are both 8:00 PM when we created the ZonedDateTime as below.
var melbCreatedTime = createdTime.InZoneLeniently(DateTimeZoneProviders.Tzdb["Australia/Melbourne"]);

// Now we can get to UTC, because we have a ZonedDateTime and therefore
// have a known offset from UTC:
sharedB.CreatedUTC = melbCreatedTime.ToDateTimeUtc();

Is this correct? DateTime logic is by far my weakest area, and I just want to make sure I understand what's happening here.

Without the comments:

var dateCreatedLocal = LocalDateTime.FromDateTime(DateTime.SpecifyKind(result.DateCreated.Value, DateTimeKind.Unspecified));
var dateCreatedUtc = dateCreatedLocal.InZoneLeniently(DateTimeZoneProviders.Tzdb["Australia/Melbourne"]).ToDateTimeUtc();
sharedB.CreatedUTC = dateCreatedUtc;

Thanks.

Upvotes: 1

Views: 335

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1501073

There's no concept of a "LocalDateTime in daylight savings". It's just a date and time, with no reference to any time zone that might or might not be observing DST.

However, if your aim is just to go from a DateTime with a Kind of Unspecified to a DateTime with a Kind of Utc using a particular time zone, I'd normally suggest using TimeZoneInfo - unless you specifically need IANA time zone ID support.

In general, I'd suggest using the Noda Time types everywhere - or if you're going to use the BCL types everywhere, don't use Noda Time at all. There are some cases where it makes sense to use Noda Time just for an isolated piece of code, and if you really need to do that here, then I believe your code should be fine - but be aware of the implications of InZoneLeniently when it comes to ambiguous or skipped local times around daylight saving changes (or other offset changes).

Upvotes: 1

Related Questions