I'm using NodaTime because of its nice support for zoneinfo data, however I have a case where I need to convert the DateTimeZone
into TimeZoneInfo
for use in Quartz.NET.
What's the recommended approach here? IANA has a mapping file between Windows time zones and zoneinfo time zones, can I create an extension method that utilises this information?
Aha, I found it - TzdbDateTimeZoneSource
has a MapTimeZoneId
method that I can pop into TimeZoneInfo.FindSystemTimeZoneById
.
Edit: MapTimeZoneId
does the mapping from Windows time zone into zoneinfo... I ended up resorting to reflection to do the mapping in the opposite direction:
using System;
using System.Collections.Generic;
using System.Reflection;
using NodaTime;
using NodaTime.TimeZones;
/// <summary>
/// Extension methods for <see cref="DateTimeZone" />.
/// </summary>
internal static class DateTimeZoneExtensions
{
private static readonly Lazy<IDictionary<string, string>> map = new Lazy<IDictionary<string, string>>(LoadTimeZoneMap, true);
public static TimeZoneInfo ToTimeZoneInfo(this DateTimeZone timeZone)
{
string id;
if (!map.Value.TryGetValue(timeZone.Id, out id))
{
throw new TimeZoneNotFoundException(string.Format("Could not locate time zone with identifier {0}", timeZone.Id));
}
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(id);
if (timeZoneInfo == null)
{
throw new TimeZoneNotFoundException(string.Format("Could not locate time zone with identifier {0}", timeZone.Id));
}
return timeZoneInfo;
}
private static IDictionary<string, string> LoadTimeZoneMap()
{
TzdbDateTimeZoneSource source = new TzdbDateTimeZoneSource("NodaTime.TimeZones.Tzdb");
FieldInfo field = source.GetType().GetField("windowsIdMap", BindingFlags.Instance | BindingFlags.NonPublic);
IDictionary<string, string> map = (IDictionary<string, string>)field.GetValue(source);
// reverse the mappings
Dictionary<string, string> reverseMap = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> kvp in map)
{
reverseMap.Add(kvp.Value, kvp.Key);
}
return reverseMap;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With