Skip to content

Instantly share code, notes, and snippets.

@jrgcubano
Created April 26, 2019 16:50
Show Gist options
  • Save jrgcubano/53e5e89cc90313586e487123145fe2d7 to your computer and use it in GitHub Desktop.
Save jrgcubano/53e5e89cc90313586e487123145fe2d7 to your computer and use it in GitHub Desktop.
NodaTime InZone() and ToZone() conversion extension methods and sample usage.
public static class DateTimeExtensions
{
/// <summary>
/// Converts a non-local-time DateTime to a local-time DateTime based on the
/// specified timezone. The returned object will be of Unspecified DateTimeKind
/// which represents local time agnostic to servers timezone. To be used when
/// we want to convert UTC to local time somewhere in the world.
/// </summary>
/// <param name="dateTime">Non-local DateTime as UTC or Unspecified DateTimeKind.</param>
/// <param name="timezone">Timezone name (in TZDB format).</param>
/// <returns>Local DateTime as Unspecified DateTimeKind.</returns>
public static DateTime ToZone(this DateTime dateTime, string timezone)
{
if (dateTime.Kind == DateTimeKind.Local)
throw new ArgumentException("Expected non-local kind of DateTime");
var zone = DateTimeZoneProviders.Tzdb[timezone];
Instant instant = dateTime.ToInstant();
ZonedDateTime inZone = instant.InZone(zone);
DateTime unspecified = inZone.ToDateTimeUnspecified();
return unspecified;
}
/// <summary>
/// Converts a local-time DateTime to UTC DateTime based on the specified
/// timezone. The returned object will be of UTC DateTimeKind. To be used
/// when we want to know what's the UTC representation of the time somewhere
/// in the world.
/// </summary>
/// <param name="dateTime">Local DateTime as UTC or Unspecified DateTimeKind.</param>
/// <param name="timezone">Timezone name (in TZDB format).</param>
/// <returns>UTC DateTime as UTC DateTimeKind.</returns>
public static DateTime InZone(this DateTime dateTime, string timezone)
{
if (dateTime.Kind == DateTimeKind.Local)
throw new ArgumentException("Expected non-local kind of DateTime");
var zone = DateTimeZoneProviders.Tzdb[timezone];
LocalDateTime asLocal = dateTime.ToLocalDateTime();
ZonedDateTime asZoned = asLocal.InZoneLeniently(zone);
Instant instant = asZoned.ToInstant();
ZonedDateTime asZonedInUtc = instant.InUtc();
DateTime utc = asZonedInUtc.ToDateTimeUtc();
return utc;
}
}
var timezone = "US/Pacific";
var utc = new DateTime(2018, 1, 9, 14, 4, 6, DateTimeKind.Utc);
var localFromUtc = utc.ToZone(timezone);
var unspecified = new DateTime(2018, 1, 9, 14, 4, 6, DateTimeKind.Unspecified);
var utcFromLocal = unspecified.InZone(timezone);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment