Reputation: 1153
For example, when I try to do the following.
TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time")
I get the error, that the TimeZone
is not available on the local computer. When I run this locally it works, but there I run it on windows. When deployed it runs on a Unix machine in Nginx. I can see that FindSystemTimeZoneById
is looking in the wrong folder when it comes to Unix. Is there any way to make this work?
Upvotes: 75
Views: 56664
Reputation: 2747
.NET Core uses system timezone. Unfortunately Windows and Linux have a different timezone system. Now you have two ways:
Upvotes: 47
Reputation: 3406
I ended up writing a small helper function:
public static TimeZoneInfo GetTimeZone(string unixId, string windowsId)
{
foreach (TimeZoneInfo timezone in TimeZoneInfo.GetSystemTimeZones())
{
if (timezone.Id == windowsId|| timezone.Id == unixId)
{
return timezone;
}
}
return null;
}
Upvotes: 0
Reputation: 181
Quick and dirty solution: serialize your TimeZoneInfo
with ToSerializedString in a dummy app on Windows, save the output, then deserialize with FromSerializedString where you need it.
On Windows:
Console.WriteLine(TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time").ToSerializedString());
Output:
Eastern Standard Time;-300;(UTC-05:00) Eastern Time (US & Canada);Eastern Standard Time;Eastern Daylight Time;[01:01:0001;12:31:2006;60;[0;02:00:00;4;1;0;];[0;02:00:00;10;5;0;];][01:01:2007;12:31:9999;60;[0;02:00:00;3;2;0;];[0;02:00:00;11;1;0;];];
Then:
// TimeZoneInfo is immutable
public static readonly TimeZoneInfo EST = TimeZoneInfo.FromSerializedString(
"Eastern Standard Time;-300;(UTC-05:00) Eastern Time (US & Canada);Eastern Standard Time;Eastern Daylight Time;[01:01:0001;12:31:2006;60;[0;02:00:00;4;1;0;];[0;02:00:00;10;5;0;];][01:01:2007;12:31:9999;60;[0;02:00:00;3;2;0;];[0;02:00:00;11;1;0;];];");
Upvotes: 5
Reputation: 22893
Starting with .NET 6, it is finally possible to work with time zones in a cross-platform manner.
The TimeZoneInfo.FindSystemTimeZoneById(string)
method automatically accepts either Windows or IANA time zones on either platform and convert them if needed.
// Both of these will now work on any supported OS where ICU and time zone data are available.
TimeZoneInfo tzi1 = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
TimeZoneInfo tzi2 = TimeZoneInfo.FindSystemTimeZoneById("Australia/Sydney");
Note that, as specified on the link, the .NET Core Alpine Linux-based Docker images do not have the necessary tzdata
installed by default, so it must be installed in your Dockerfile
for this to work correctly.
Upvotes: 31
Reputation: 1675
Working of off the previous answer, we can avoid the expensive try/catch
by checking which OS we're running on:
using System;
using System.Runtime.InteropServices;
TimeZoneInfo easternStandardTime;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
easternStandardTime = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
easternStandardTime = TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
easternStandardTime = TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
}
Upvotes: 48
Reputation: 1970
I was able to support this use-case in my development docker image by doing the following:
cp /usr/share/zoneinfo/America/Los_Angeles "/usr/share/zoneinfo/Pacific Standard Time"
Obviously, I don't think that would be a good idea for production deployments. But it might help in some scenarios.
Upvotes: 13
Reputation: 542
If you want to try a Windows time zone and then fallback on a IANA one if the Windows one doesn't exist:
var tzi = TimeZoneInfo.GetSystemTimeZones().Any(x => x.Id == "Eastern Standard Time") ?
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time") :
TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
Upvotes: 17
Reputation: 385
Can you please try this?
TimeZoneInfo easternZone;
try
{
easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
}
catch (TimeZoneNotFoundException)
{
easternZone = TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
}
You can review the list of IANA time zones here https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
Upvotes: 25