Переполнение DateTime в .NET - PullRequest
       3

Переполнение DateTime в .NET

0 голосов
/ 19 октября 2018

У нас есть серверная часть Scala / Java, которая генерирует эквивалент DateTime.MaxValue в .NET.

Мне прислали следующую дату в виде строки "9999-12-31T23: 59: 59.999999999Z".

Если я использовал DateTime.TryParse("9999-12-31T23:59:59.999999999Z", out var dateTime), то выдается ArgumentOutOfRangeException (добавленное или вычтенное значение приводит к непредставляемому имени DateTime.Parameter: value).

Я не ожидал этого, так как я звонил Try Parse.Возможно, возвращение false было бы более интуитивно понятным?

Если я уменьшу год, я вижу, что .NET переносит дату на следующий день, что, очевидно, не будет работать с максимальной датой / временем!

DateTime.TryParse("9998-12-31T23:59:59.999999999Z", out var dateTime);
dateTime.ToString().Dump();

Выходы: 01/01/9999 00: 00: 00

Если я уменьшу точность мс на 2, то это сработает:

DateTime.TryParse("9998-12-31T23:59:59.9999999Z", out var dateTime);
dateTime.ToString().Dump();

Выходы:31/12/9998 23: 59: 59

Это действительно похоже на ошибку в .NET?Это ожидаемое поведение?

Ответы [ 2 ]

0 голосов
/ 09 января 2019

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

Попробуйте выполнить следующее:

DateTime.MaxValue.ToString("o")
это приведет к "9999-12-31T23: 59: 59.9999999", а не "9999-12-31T23:59: 59.999999999Z ", то есть на два меньше девяток в конце.

Используйте "9999-12-31T23:59:59.9999999Z" в качестве входных данных, и он будет успешно проанализирован в DateTime.MaxValue.

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

DateTime.TryParse("9999-12-31T23:59:59.9999999Z", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTime);
0 голосов
/ 12 ноября 2018

Передача значений Min / Max / Infinity и т. Д. Между разными платформами - плохая идея.Каждая платформа может иметь свое собственное представление специальных значений (не только дат).Поэтому единственно допустимым вариантом является передача значений эпох (параметры миллисекунд предпочтительнее в большинстве случаев), поскольку они известны обеим сторонам.

Если вышесказанное по какой-то причине невозможно, у вас есть две опции некрасиво :

  1. Замените специальные значения в выходных данных Scala / Java на вашисобственная «кодировка».Например, как «MaxValue», или выбирайте по своему усмотрению.На стороне .Net вы будете определять специальные значения и переводить их соответствующим образом.

  2. Вставьте простую предварительную обработку в ваш код .Net.Например, проверьте "9999-12-31T23:59:59.999999999".StartsWith("9999") для максимальных значений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...