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
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;
///
/// Extension methods for .
///
internal static class DateTimeZoneExtensions
{
private static readonly Lazy> map = new Lazy>(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 LoadTimeZoneMap()
{
TzdbDateTimeZoneSource source = new TzdbDateTimeZoneSource("NodaTime.TimeZones.Tzdb");
FieldInfo field = source.GetType().GetField("windowsIdMap", BindingFlags.Instance | BindingFlags.NonPublic);
IDictionary map = (IDictionary)field.GetValue(source);
// reverse the mappings
Dictionary reverseMap = new Dictionary();
foreach (KeyValuePair kvp in map)
{
reverseMap.Add(kvp.Value, kvp.Key);
}
return reverseMap;
}
}