I have two DateTime
objects which contain two UTC date/times and a users TimezoneId (tzdb) as a string
. I'm trying to write a method that takes these three parameters and returns the total seconds (or Duration
) between the two datetimes relative to the timezone.
public static double GetDurationForTimezone(DateTime startUtc, DateTime endUtc, string timezoneId)
{
var timezone = DateTimeZoneProviders.Tzdb.GetZoneOrNull(timezoneId);
// convert UTC to timezone
var startInstantUtc = Instant.FromDateTimeUtc(startUtc);
var startZonedDateTime = startInstantUtc.InZone(timezone);
var endInstantUtc = Instant.FromDateTimeUtc(endUtc);
var endZonedDateTime = endInstantUtc.InZone(timezone);
return endZonedDateTime.ToInstant().Minus(startZonedDateTime.ToInstant()).ToTimeSpan().TotalSeconds;
}
I want to do it w.r.t. the timezone, to ensure it takes into account any possible Daylight Saving changes that may occur throughout this period.
Example test:
// DST starts (25h day -- DST starts: 10/4 @ 2am local time)
var result = GetDurationForTimezone(
new DateTime(2015, 10, 3, 15, 0, 0, DateTimeKind.Utc),
new DateTime(2015, 10, 4, 15, 0, 0, DateTimeKind.Utc),
"Australia/Sydney");
Assert.Equal(TimeSpan.FromHours(25).TotalSeconds, result);
But when running this test, it seems like the calls to .ToInstant()
are not adhering to the ZonedDateTime
versions, but rather the original UTC DateTime
objects. Thus I'm seeing the result be 24 hours.