Почему я не могу добавить месяцы в OffsetDateTime? - PullRequest
3 голосов
/ 25 апреля 2019

Я использую NodaTime для управления датами и часовыми поясами в .Net Core WebApi.Одним из типов в библиотеке является OffsetDateTime, который очень похож на DateTimeOffset из .Net Framework.Я использую его везде, чтобы манипулировать датами явным и прозрачным способом, поскольку даты иногда бывают в системном часовом поясе и часовом поясе пользователя.

Мне нужно добавить месяц к определенной дате в определенный момент, но я не могу добавить месяц к объекту OffsetDateTime, все, что я могу сделать, это добавить до часов или тип с именем Duration, который является календарным-независимый.Если бы это был тип Instant, я бы понял, так как Instant представляет момент времени действительно абстрактно, но не OffsetDateTime.OffsetDateTime даже имеет свойство «Календарь», которое действительно показывает, что оно привязано к календарной системе, которая должна позволять вам делать арифметику, как я хочу, без необходимости выполнять преобразования типов и т. Д.

Кроме того, DateTimeOffset (из .net framework) позволяет добавлять месяцы, но я хочу быть последовательным и везде использовать одни и те же типы.

Короче говоря, я не могу сделать:

public OffsetDateTime GetPreviousMonth(OffsetDateTime input)
{
    return input.AddMonths(-1)
}

Я могу только сделать:

offsetDateTime.PlusHours(15)
offsetDateTime.PlusMinutes(3000)
offsetDateTime.Minus(Duration.FromMinutes(60))
offsetDateTime.Minus(Duration.FromHours(1))

Любая идея, как я могу решить эту проблему, не проходя преобразования типов?Может быть, я что-то упустил в документации, но я так не думаю.

Ответы [ 2 ]

3 голосов
/ 25 апреля 2019

OffsetDateTime представляет собой локальное время даты со смещением от UTC И мгновенным.

Однако оно не привязано к временной зоне.

По этой причине вы можете добавить из нее «фиксированную» сумму, например, секунды, минуты и часы, поскольку они не являются зависимыми от TimeZone.

Вы не можете вычесть из нее месяц, так как это возможноНе знаю, был ли переход дневного света в течение последнего месяца.

Я знаю, что вы просили решение без преобразования типов, но на самом деле вы не можете.Чтобы справиться с этим правильно, вы должны преобразовать его в ZonedDateTime с правильным часовым поясом.Любое решение без указания часового пояса может привести к неправильному результату.

2 голосов
/ 25 апреля 2019

Вы можете использовать OffsetDateTime.With, что позволяет вам установить регулятор LocalDate.Вы можете работать (Plus, Minus, ...) на LocalDate с Period, который позволяет указывать промежутки времени в месяцах:

public OffsetDateTime GetPreviousMonth(OffsetDateTime input)
{
    return input.With((LocalDate ld) => ld.Minus(Period.FromMonths(1)));
}
...