Arhn - архитектура программирования

NodaTime Неверный DateTime.Kind для Instant.FromDateTimeUtc

Я пытаюсь решить эту проблему с часовым поясом. Мы хотели бы сохранить все DateTime в формате UTC, а затем преобразовать DateTime в часовой пояс пользователя.

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

Вот как мы конвертируем DateTime в UTC (обратите внимание — я пока жестко запрограммировал usersTimeZone):

public static DateTime ConvertLocaltoUTC(this DateTime dateTime)
{
    LocalDateTime localDateTime = LocalDateTime.FromDateTime(dateTime);

    IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb;
    var usersTimezoneId = "Europe/Copenhagen";
    var usersTimezone = timeZoneProvider[usersTimezoneId];

    var zonedDbDateTime = usersTimezone.AtLeniently(localDateTime);
    var returnThis = zonedDbDateTime.ToDateTimeUtc();
    return zonedDbDateTime.ToDateTimeUtc();
}

И вот как мы конвертируем его обратно:

public static DateTime ConvertUTCtoLocal(this DateTime dateTime)
{
    Instant instant = Instant.FromDateTimeUtc(dateTime);
    IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb;
    var usersTimezoneId = "Europe/Copenhagen"; //just an example
    var usersTimezone = timeZoneProvider[usersTimezoneId];
    var usersZonedDateTime = instant.InZone(usersTimezone);
    return usersZonedDateTime.ToDateTimeUnspecified();
}

Однако, когда мы конвертируем его обратно в местное время, возникает исключение:

Исключение аргумента: неверный DateTime.Kind для Instant.FromDateTimeUtc

в первой строке ConvertUTCtoLocal().

Примером DateTime может быть: «18.09.2017 17:28:46» — да, это было с помощью метода ConvertLocalToUTC.

Я предоставляю неправильный формат? Что я здесь делаю неправильно?

18.09.2017

  • Предоставьте минимально воспроизводимый пример. Значение, возвращаемое из ZonedDateTime.ToDateTimeUtc(), безусловно, должно быть Utc, что и требуется для Instant.FromDateTimeUtc. Я предполагаю, что DateTime, которое вы передаете в ConvertUTCtoLocal, не является результатом вызова ConvertLocalToUTC. Тем не менее, я бы рекомендовал вообще избегать использования DateTime, если вы возможно можете — используйте типы Noda Time насколько это возможно. 20.09.2017
  • (Было бы также полезно указать версию Noda Time, которую вы используете.) 20.09.2017
  • Пожалуйста, обновите этот вопрос с дополнительной информацией. Как отмечается как в комментариях, так и в ответах, проблема заключается в другом, что означает, что на данный момент это бесполезный вопрос. 27.09.2017
  • Должны ли мы предположить, что вас больше не интересует этот вопрос, поскольку вы не уточнили его? 21.11.2017
  • Привет, Джон, я решил проблему из-за поврежденных данных в моей базе данных. Приносим извинения за доставленные неудобства 21.11.2017
  • Если это проблема, которую вы не можете воспроизвести, я бы сказал, что это бесполезный вопрос - я бы предложил удалить его. Вы, вероятно, не можете, пока присутствует ответ Мэтта, но я подозреваю, что он захочет удалить свой ответ, если вопрос будет удален. (Если вы можете найти случай, когда вопрос действительно действительно имеет смысл, это другое дело.) 21.11.2017

Ответы:


1

Исключение, которое вы показываете:

Исключение аргумента: неверный DateTime.Kind для Instant.FromDateTimeUtc

Выбрасывается из этого кода:

Instant instant = Instant.FromDateTimeUtc(dateTime);

Это означает, что dateTime.Kind должно быть DateTimeKind.Utc, чтобы его можно было преобразовать в Instant, а по какой-то причине это не так.

Если вы посмотрите на результат вашего метода ConvertLocaltoUTC, вы обнаружите, что он действительно имеет .Kind == DateTimeKind.Utc.

Итак, проблема заключается в другом месте вашего кода, где бы вы ни создали dateTime, который вы передаете ConvertUTCtoLocal.

Вы можете обнаружить, что решение может быть любым из следующих:

  • Возможно, вам придется вызвать DateTime.SpecifyKind, чтобы установить тип в формате UTC, но будьте осторожны, делайте это только тогда, когда ваши значения на самом деле являются UTC, и он просто не устанавливает вид. Например, используйте это при загрузке DateTime на основе UTC из базы данных.

  • Возможно, вам придется позвонить .ToUniversalTime(), но будьте осторожны и делайте это только в том случае, если местный часовой пояс машины имеет отношение к вашей ситуации. Например, сделайте это в настольных или мобильных приложениях, где элемент управления пользовательского интерфейса выбирает дату, но вы имели в виду, что это означает UTC, а не местное время.

  • Возможно, вам потребуется изменить способ разбора строк в значения DateTime, например, путем передачи DateTimeStyles.RoundTripKind вызову DateTime.Parse (или любому из его вариантов. Например, сделайте это, если вы читаете данные из текста, CSV , и т.д.

Если вы хотите избежать принятия решения, не пишите функции, которые принимают DateTime в качестве входных данных или дают DateTime в качестве выходных данных. Вместо этого используйте DateTimeOffset или типы Noda-Time, такие как Instant, LocalDateTime и т. д., как можно раньше.

20.09.2017

2

Вот что сработало для меня:

Instant instant = Instant.FromDateTimeUtc(DateTime.SpecifyKind(datetime, DateTimeKind.Utc));
16.01.2020
Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..