Convert NodaTime DateTimeZone into TimeZoneInfo

后端 未结 4 2016
天涯浪人
天涯浪人 2021-02-14 04:40

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

4条回答
  •  故里飘歌
    2021-02-14 04:54

    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;
        }
    }
    

提交回复
热议问题