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?
Thanks, Dean
I would avoid using reflection if possible. I wouldn't like to bet on your approach working with future versions :)
Feel free to file a feature request for this functionality for future versions, but for the moment I'd build up your reverse dictionary in a more stable way:
Of course, this won't cover all the time zones in TZDB. In fact, it won't even give all the information we could give based on the CLDR information we use... CLDR gives multiple mappings for each Windows ID, and we only store the first one at the moment. We've been trying to work out how to expose more of that, but haven't managed yet. Thoughts welcome on the Noda Time mailing list :)
Also note that just because there's a mapping between the BCL and TZDB zones doesn't mean they'll actually give the same results for everything - it's just the closest mapping available.
You can use TimeZoneConverter library by Matt Johnson.
ZoneId used by NodeTime TzdbZoneLocation is IANA time zone, so you can get TimeZoneInfo like this:
Don't forget to wrap it with try-catch with some kind of fallback just in case.
Also look at original Matt Johnson solution for converting between IANA time zone and Windows time zone.
However none of this works in a PCL because most of the work is done by .NET in the .GetSystemTImeZones() and .FindSystemTIemZoneById() methods - which don't exist in PCL.
I'm stunned that for all the info you can get out of NodaTime, getting something as simple as "EST" abbreviation when you already have the zone name of "US/Eastern" seems to have stopped me in my tracks.
Aha, I found it -
TzdbDateTimeZoneSource
has aMapTimeZoneId
method that I can pop intoTimeZoneInfo.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: