«Америка / Денвер» - это название IANA для этого часового пояса. База данных часовых поясов (tzdb) содержит эти имена и их правила (которые могут меняться со временем). NodaTime использует данные tzdb для выполнения своего logi c.
Вы можете использовать пакет TimeZoneConverter для преобразования TimeZoneInfo
в идентификатор часового пояса tzdb.
Вы Я задал несколько вопросов, связанных с этим, и я хотел бы собрать некоторые из них для вас здесь.
NodaTime All The Way Down
Если это возможно, вам следует попросите потребителя передать вам ZonedDateTime
. Это единое значение со всей информацией, необходимой базовому движку на основе Java, а это именно то, что вы просили ( здесь ). Использование единственного значения, которое было проверено в домене (в отличие от настраиваемого контейнера для составных частей), откладывает действия, подверженные ошибкам, для потребителя, который лучше подходит для их устранения, чем вы, и должен сделайте перед тем, как позвонить своему клиенту. Тогда вам не нужно нести ответственность за какие-либо ошибки или недочеты, связанные с тем, что вас не должно волновать. предоставит вам строку в формате, ожидаемом стороной Java.
ZonedDateTimePattern customPattern = ZonedDateTimePattern.Create(
"uuuu'-'MM'-'dd'T'HH':'mm':'sso<Z-HH':'mm>'['z']'",
CultureInfo.InvariantCulture,
mapping => mapping.LocalDateTime.InZoneLeniently(mapping.Zone),
DateTimeZoneProviders.Tzdb,
default);
Судя по вашим предыдущим вопросам, похоже, что вам нужен буквальный «Z
» для UT C вместо «+00:00
". Это делает подшаблон «Z-HH':'mm
». Взгляните на документацию Шаблоны смещения , если вам нужно что-то другое.
Теперь вы можете использовать customPattern
для создания строки, которую нужно отправить.
string formatted = customPattern.Format(zonedDateTime);
Тот же шаблон можно использовать для синтаксического анализа такой строки до ZonedDateTime
, если необходимо.
Использование NodaTime только для внутренних целей
Если вы не можете ожидать, что потребитель будет работать с типами NodaTime , это нормально. Получение DateTimeOffset
и TimeZoneInfo
также может работать. Вы можете без особых церемоний преобразовать их в ZonedDateTime
в своем клиенте.
// Given: DateTimeOffset dateTimeOffset, TimeZoneInfo timeZoneInfo
DateTimeZone dateTimeZone = DateTimeZoneProviders.Tzdb[TZConvert.WindowsToIana(timeZoneInfo.Id)];
ZonedDateTime zonedDateTime = OffsetDateTime.FromDateTimeOffset(dateTimeOffset).InZone(dateTimeZone);
Потенциальная проблема с этим состоит в том, что коллективный ввод не был проверен в домене. Мэтт Джонсон-Пинт в своем ответе указал, что может быть передано смещение, которое не соответствует указанному часовому поясу. Будьте готовы добавить проверку или попытку / уловку, чтобы вы могли очень ясным языком рассказать потребителю, что он сделал не так.
Принятие неоднозначного времени
Вы могли бы принять DateTime
, но вы будете вынуждены сделать предположения о двусмысленных временах, которые могут быть неприемлемы для вас и / или потребителя. Затем вы берете на себя ответственность за logi c, который не имеет ничего общего с функциональностью вашего API.
Я включу его сюда для полноты, но это не является одобрением какого-либо рода.
// Given: DateTime dateTime, TimeZoneInfo timeZoneInfo
DateTimeZone dateTimeZone = DateTimeZoneProviders.Tzdb[TZConvert.WindowsToIana(timeZoneInfo.Id)];
ZonedDateTime zonedDateTime = LocalDateTime.FromDateTime(dateTime).InZoneLeniently(dateTimeZone);
InZoneLeniently
- это большой красный флаг. Он будет "просто делать это", когда встречается неоднозначное время, и это может быть неправильно. Помните, что «просто» - это четырехбуквенное слово.