Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I fetch TimeZoneInfo in a platform-agnostic way?

I'm working on porting a .NET Framework 4.5 app to .NET Core 2.0 and have started to do some testing on my Mac. When I run this code on .NET Core 2.0 on Windows it works fine:

TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");

but it throws the following exception on the Mac:

System.TimeZoneNotFoundException: The time zone ID 'Pacific Standard Time' was not found on the local computer. ---> System.IO.FileNotFoundException: Could not find file '/usr/share/zoneinfo/Pacific Standard Time'.
   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
   at System.IO.File.ReadAllBytes(String path)
   at System.TimeZoneInfo.TryGetTimeZoneFromLocalMachine(String id, TimeZoneInfo& value, Exception& e)
   --- End of inner exception stack trace ---
   at System.TimeZoneInfo.FindSystemTimeZoneById(String id)

After some poking around, it seems that using the time zone ID "America/Los_Angeles" fixes the problem on the Mac.

I'm wondering what I should do to keep this platform agnostic. Should I try to find "Pacific Standard Time", and then try to find "America/Los Angeles" in a catch block? That seems clumsy, and what if another platform has yet another string for it? Is there a better way to look up the TimeZoneInfo I want?

like image 284
Rikki Gibson Avatar asked Dec 16 '17 17:12

Rikki Gibson


1 Answers

This is a known problem, and is tracked in dotnet/corefx#11897. There's no built-in solution yet.

However, my TimeZoneConverter library can be used for this.

TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("Pacific Standard Time");

It works by first seeing if the time zone is present on the computer. If not, then it converts to the equivalent time zone in IANA format (America/Los_Angeles in this case), and trying to retrieve it with that instead. The opposite case also works, so you can use either format on any OS.

like image 125
Matt Johnson-Pint Avatar answered Nov 19 '22 10:11

Matt Johnson-Pint