Каковы варианты использования спецификатора формата DateTime в .NET (UU)? - PullRequest
0 голосов
/ 27 октября 2019

(Предисловие: этот вопрос не предназначен для того, чтобы быть слишком широким или основанным на мнениях, хотя он обязательно субъективен).

Я обнаружил ошибку в моем программном обеспечении, которая использовала dtValue.ToString( "U", CultureInfo.InvariantCulture ) вместо dtValue.ToString( "u", CultureInfo.InvariantCulture ).

(Полагаю, это произошло потому, что, хотя "R" и "r", "O" и "o" различаются в буквенном регистре, .NET обрабатывает их идентично, тогда как "U" и "u" представляют очень разные форматы и поведения).

После исправления этой проблемы я посмотрел документацию для U формата из любопытства и спросил, почему он существует в первомместо, потому что я не могу придумать сценарий использования для U.

Для тех, кому интересно: U делает это:

  1. Если это значение DateTimeOffset, тоFormatException выбрасывается всегда.
  2. Если это значение DateTime, то внутренне оно преобразуется в UTC с использованием DateTime.ToUniversalTime:
    • Если value.Kind == DateTimeKind.Utc, то преобразование не выполняется.
    • Если value.Kind == DateTimeKind.Local или Unspecified, то текущий UT системного часового пояса локального компьютераСмещение C применяется для преобразования его в UTC.
  3. Затем значение форматируется с использованием формата "F" (DateTimeFormatInfo.FullDateTimePattern), который зависит от конкретной культуры.
    • InvariantCulture использует "dddd, dd MMMM yyyy HH:mm:ss".
    • en-US использует "dddd, MMMM d, yyyy h:mm:ss tt".
    • en-GB использует "dd MMMM yyyy HH:mm:ss".

Мои рассуждения:

  • Поскольку формат зависит от культуры, его нельзя использовать для связи между машинами.
    • Если, конечно, вы не используете InvariantCulture, но результирующая выходная строка содержит избыточную информацию (название дня) и трудна для анализа информации (полные названия месяцев на английском языке), в то время как машиночитаемое форматирование неизменно использует вариациюISO 8601 yyyy-MM-dd HH:mm[:ss][zzz].
  • При преобразовании теряется информация, такая как местное время или местное смещение UTC.
  • Часто программы будут обрабатывать разные DateTimeзначения без учета DateTimeKind (например, программы, использующие значение DateTimeKind.Local, как если бы оно представляло UTC, особенно если часовой пояс локального компьютера - время UTC или британское время (и, таким образом, вы получаете интересные ошибки во время британского летнего времени).
    • Так что, если вы собираетесь switch или перейти на dtValue.Kind, чтобы явно указывать на преобразование в UTC, тогда вы можете также использовать F и избегать неявного UTC U преобразования.
    • Я ожидал, что DateTimeKind.Unspecified значения, отформатированные с U, вызовут исключение, потому что смещение значения не указано - это удивительно, чтоt ToUniversalTime() использует текущее смещение часового пояса локального компьютера (как с Local) вместо того, чтобы жаловаться на предположение. (Тем не менее, именно поэтому мы должны использовать DateTimeOffset или NodaTime везде, где это возможно, конечно).
  • DateTimeOffset просто не поддерживает его (по-видимому, это было намеренно отучить программистов .NET от его использования?).

Мой вопрос:

"Вы когда-либо преднамеренно использовали спецификатор формата U или видели, что он использовалв рабочем коде? Почему? Это была хорошая идея в то время и все еще хороший выбор? "

...