Если вы ранее разрабатывали кроссплатформенное приложение, вы могли столкнуться с ситуацией, когда разные платформы по-прежнему имеют разную производительность, несмотря на использование кроссплатформенного решения. И в этом посте будет обсуждаться ситуация, когда результат получения данных о часовом поясе различается на разных платформах в .NET Core.

Получение данных о часовых поясах на платформе Windows

Во-первых, давайте создадим новое консольное приложение .NET Core на платформе Windows. В этом случае я возьму в качестве примера новозеландское время.

using System;
namespace DotNETTips
{
    class Program
    {
        static void Main(string[] args)
        {
            var dateTime = DateTime.UtcNow;
            Console.WriteLine($"dateTime in UTC : {dateTime}");
            var nzTzInfo = TimeZoneInfo.FindSystemTimeZoneById("New Zealand Standard Time");
            dateTime = TimeZoneInfo.ConvertTimeFromUtc(dateTime, nzTzInfo);
            Console.WriteLine($"dateTime in NZ Time Zone : {dateTime}");
            Console.ReadKey();
        }
    }
}

В приведенном выше коде идентификатором часового пояса Новой Зеландии на платформе Windows является «Стандартное время Новой Зеландии», как вы можете видеть на снимке экрана ниже.

И если вас интересует тема данных о часовых поясах на платформе Windows, вы можете найти список часовых поясов по умолчанию в Windows по следующей ссылке.



Следовательно, мы можем получить данные TimeZoneInfo Новой Зеландии, вызвав метод FindSystemTimeZoneById.

TimeZoneInfo.FindSystemTimeZoneById("New Zealand Standard Time");

Затем мы можем преобразовать данные даты и времени в формате UTC в NZDT.

TimeZoneInfo.ConvertTimeFromUtc(dateTime, nzTzInfo);

Приведенный выше код на самом деле очень хорошо работает на платформе Windows, и вы можете обнаружить, что дата и время печатаются в терминале, как и ожидалось.

Получить данные о часовом поясе в macOS / Linux

Однако, если вы хотите запустить тот же код на своем ноутбуке Mac Pro или компьютере с Linux, он будет распечатывать не дату и время в часовом поясе Новой Зеландии, а TimeZoneNotFoundException.

Это не потому, что на вашем Mac Pro не установлены данные о часовых поясах, но в macOS используется другой поставщик данных о часовых поясах - База данных часовых поясов IANA.

В отличие от идентификатора часового пояса на платформе Windows, идентификатор часового пояса IANA для Новой Зеландии - «Pacific / Auckland». И для вас также есть список часовых поясов, вы можете щелкнуть следующую ссылку, чтобы проверить список часовых поясов в базе данных часовых поясов.



Следовательно, если вы хотите, чтобы ваш код работал должным образом, вам необходимо изменить аргумент метода FindSystemTimeZoneById с «Стандартное время Новой Зеландии» на « Pacific / Auckland » в macOS / Linux.

И правильная дата-время будет напечатана в консоли. Поэтому, если ваше приложение будет работать на разных платформах, вам нужно будет учесть различия.

Решение

Однако, если вы не хотите самостоятельно разбираться с различиями, поскольку их сложно поддерживать, на GitHub есть доступный пакет с открытым исходным кодом, который может помочь вам решить эту проблему.



TimeZoneConverter - это легкая библиотека для быстрого преобразования между именами часовых поясов IANA, Windows и Rails.

Мы можем очень легко установить пакет через NuGet.

Я использовал VS Code в macOS для установки этого пакета NuGet, затем изменил FindSystemTimeZoneById на GetTimeZoneInfo и передал методу тот же идентификатор / идентификатор часового пояса, что и в Windows, «Стандартное время Новой Зеландии». И код напечатал правильный результат в консоли.

Таким образом, мы можем работать с разными поставщиками часовых поясов единообразно, а наш код легче поддерживать.

Спасибо за чтение и надеюсь, что это полезно.

Поболтать в