6

I use NodaTime to do time zone conversions in ical.net, because it performs much better than the previous implementation which tried to use the VTIMEZONE element to handle time changes and time zone conversions.

Under the hood, this method is pretty important for performance: it drops the test suite runtime from about 6 seconds to around 2.5.

public static DateTimeZone GetZone(string tzId)
{
    // IANA lookup attempt

    zone = DateTimeZoneProviders.Bcl.GetZoneOrNull(tzId);
    if (zone != null)
    {
        return zone;
    }

    // Serialization lookup attempt
    // Some other tricks to find a reasonable time zone, etc.
}

The .NET Core implementation of NodaTime does not have Bcl as a DateTimeZoneProvider. (It still has Tzdb and Serialization.) I poked around in the NodaTime source a bit, but I wasn't sure what the replacement was meant to be, if any.

What should we be using for BCL time zone lookups in the .NET Core port of NodaTime?

svick
  • 236,525
  • 50
  • 385
  • 514
rianjs
  • 7,767
  • 5
  • 24
  • 40

1 Answers1

4

What should we be using for BCL time zone lookups in the .NET Core port of NodaTime?

Unfortunately, there isn't good TimeZoneInfo support in the PCL profile that Noda Time 1.x supports - even FindSystemTimeZoneById() and the Id property aren't provided. As noted in comments, there's encouraging signs that they might be in .NET Core itself - I'll need to look.

You could use TzdbDateTimeZoneSource.WindowsMapping to get the nearest equivalent IANA/TZDB time zone... but ideally, it would be better if you could use IANA/TZDB time zone IDs throughout your code. (Those will be more portable for other platforms, too.)

Even if FindSystemTimeZoneById is supported on .NET Core, it won't provide the Windows time zones if you're on Linux - it uses the zoneinfo files. So if you need Windows time zone portability, I think WindowsMapping really is the best option.

Update: Having just looked again, we definitely can't support TimeZoneInfo in .NET Core, as it doesn't expose adjustment rules :(

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • If I could mandate that the whole world use IANA time zones, I would. Alas, ical.net is a library for creating and consuming icalendar (ics) files generated from applications like Google Calendar, Outlook, Apple Mail, etc. so it has to be pretty permissive in what it supports. E.g.: https://github.com/rianjs/ical.net/blob/master/ical.NET.UnitTests/Calendars/Serialization/TimeZone3.ics#L5 – rianjs Jul 04 '16 at 19:19
  • FindSystemTimeZoneById exists: https://learn.microsoft.com/en-us/dotnet/core/api/system.timezoneinfo#System_TimeZoneInfo_FindSystemTimeZoneById_System_String_ as does the Id property: https://learn.microsoft.com/en-us/dotnet/core/api/system.timezoneinfo#System_TimeZoneInfo_Id -- are they unsupported in some other way? – rianjs Jul 04 '16 at 19:27
  • @rianjs: Hmm... they didn't exist in the previous profiles I was targeting (and that 1.x target). Will have another look now with .Net Core... although I've found a few things which say "supported in PCL" but then don't actually build. Docs for versioning leave a lot to be desired. – Jon Skeet Jul 04 '16 at 19:31
  • @rianjs: One thing to note: on Linux I'd expect FindSystemTimeZoneById to only work with IANA IDs, not Windows ones. They've wrapped the IANA zones in the Windows API. So in that case, you'd still need the Windows mapping. – Jon Skeet Jul 04 '16 at 19:33