Получить локальный DateTime в Дании с сервера в Ирландии - PullRequest
0 голосов
/ 28 октября 2019

У меня есть решение в Azure в Ирландии. Я живу в Дании.

Было бы правильно сохранить все мои времена и даты как universal = DateTime.Now.ToUniversalTime() в моей базе данных в Ирландии?

Когда мне нужно датское время, я не могу: universal.ToLocalTime() потому что я все еще на сервере в Ирландии. Вместо этого я мог бы написать:

danish = TimeZoneInfo.ConvertTimeFromUtc(universal, TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time"));

Но я думаю, что это долгий путь.

Альтернатива 1: я конвертирую дату в датский, прежде чем сохранить в своей базе данных в Ирландии. Альтернатива 2: между Данией и Ирландией существует один часовой пояс, поэтому я мог бы: danish = dateTime.AddHours(1), но, возможно, это может привести к ошибкам в летнее и зимнее время.

Ответы [ 2 ]

4 голосов
/ 28 октября 2019

Несколько вещей:

  • Там нет ничего неправильно с записью DateTime.Now.ToUniversalTime(), но следует понимать, что под капотом, который выбирает текущее время UTC, преобразуя впо местному времени, а затем переводим обратно в UTC. Таким образом, и короче, и эффективнее просто позвонить DateTime.UtcNow, чтобы получить время UTC напрямую без преобразований.

  • Сервер, на котором работает ваш код, не имеет значения (или должен быть),Кроме того, для всех экземпляров Azure часовой пояс в любом случае установлен на UTC, поэтому вы не увидите никаких эффектов от местного часового пояса Ирландии.

  • Да, "Romance Standard Time" - правильный идентификатор Windowsпо местному времени в Дании. Если вы работаете на платформе, отличной от Windows, вы должны использовать "Europe/Copenhagen". Если вы пишете для многоплатформенного использования, тогда используйте "Europe/Copenhagen" с моей библиотекой TimeZoneConverter .

  • Если вы просто хотите написать короче код, вы можете сделать следующее:

    DateTime danish = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(universal, "Romance Standard Time");
    

    Я говорю может , потому что это будет правильно, только если DateTime у вас есть universal переменная имеет Kind свойство, установленное на DateTimeKind.Utc. Если вы установили это ранее, используя DateTime.SpecifyKind, то это будет работать. С другой стороны, если вы только что получили это значение из базы данных, то по умолчанию Kind будет DateTimeKind.Unspecified. Основное отличие состоит в том, что ConvertTimeFromUtc обрабатывает DateTimeKind.Unspecified, как если бы оно было DateTimeKind.Utc, тогда как ConvertTimeBySystemTimeZoneId обрабатывает DateTimeKind.Unspecified, как если бы оно было DateTimeKind.Local.

    Другими словами, если вы неЕсли установить Kind явно, он будет конвертироваться из местного времени в датское время. Однако , поскольку Azure использует местный часовой пояс как UTC, вы получите тот же результат. Просто вы можете получить другие результаты при работе в другом месте.

  • Вы можете рассмотреть возможность использования DateTimeOffset вместо DateTime. Это обычно приводит к более ясному коду и меньшему количеству ошибок. (DateTimeKind не используется с DateTimeOffset.) Конечно, это зависит от того, для чего именно вы используете эти данные, но часто это хорошая идея.

О вашем предложенномальтернативы, я не предлагаю ни один. Ваш оригинальный код лучше. Мои мысли по каждому:

Альтернатива 1: я конвертирую дату в датский, прежде чем сохранить в своей базе данных в Ирландии.

Это зависит от того, что вы представляете.

  • Если это уникальный момент времени (время, когда что-то произошло ,обычно в прошлом) - тогда вы должны сохранить его как UTC. Это позволяет правильно преобразовать в любой часовой пояс.

  • С другой стороны, если вы представляете время, когда что-то запланировано (в будущем), тогдаЧаще всего это местное время. Это особенно важно для повторяющихся событий в часовых поясах с переходом на летнее время или событий в часовых поясах, которые могут быть нестабильными (когда правительство часто вносит изменения в короткие сроки).

Альтернатива2: Между Данией и Ирландией есть один часовой пояс, поэтому я мог бы: danish = dateTime.AddHours(1), но, возможно, это могло бы привести к ошибкам с летним и зимним временем.

Вы не должны добавлять или вычитать время для корректировкичасовые пояса. В конце концов - вы не говорите о другом моменте времени - часе в будущем или часе в прошлом. ( См. Юмористический пример этого здесь ).

Кроме того, Дания и Ирландия сегодня могут быть похожими, но это не значит, что они всегда были такимии это не значит, что они обязательно останутся такими в будущем. В Ирландии используются разные идентификаторы часовых поясов ("GMT Standard Time" в Windows, "Europe/Dublin" на других платформах).

2 голосов
/ 28 октября 2019

Используйте время сервера Utc для сохранения записи в database, чтобы избежать разницы во времени при преобразовании даты и времени from и последующем преобразовании back. Как только запись использует Utc datetime, вы можете легко преобразовать ее в любой часовой пояс, например: система требует преобразовать дату и время в местное время Дании, и в будущем может потребоваться отображение в Германии даты и времени

DateTime timeUtc = DateTime.UtcNow;
TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time");
DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...