为什么我不能在OffsetDateTime上增加几个月?

时间:2019-04-25 17:23:01

标签: c# asp.net-core nodatime

我正在使用NodaTime来管理.Net Core WebApi中的日期和时区。库中的一种类型是OffsetDateTime,它与.Net框架中的DateTimeOffset非常相似。由于日期有时会进入系统时区和用户时区,因此我在任何地方都使用它以显式和透明的方式操作日期。

我需要在某个点的某个日期添加一个月,但是我不能在OffsetDateTime对象中添加一个月,我所能做的就是加起来直到几小时或一个与日历无关的称为Duration的类型。如果是Instant类型,我会理解,因为Instant以一种非常抽象的方式表示一个时间点,而不是OffsetDateTime。 OffsetDateTime甚至具有一个“ Calendar”属性,该属性确实表明它已绑定到日历系统,该日历系统应允许您执行我想做的算术运算,而不必进行类型转换等。

最重要的是,(来自.net框架)DateTimeOffset允许您添加月份,但我希望保持一致,并在各处使用相同的类型。

长话短说,我做不到:

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 个答案:

答案 0 :(得分:3)

OffsetDateTime代表本地日期时间,与世界标准时间(UTC)偏移,并带有瞬间。

但是,它未绑定到TimeZone。

由于这个原因,您可以在其中添加“固定”金额,例如秒,分钟和小时,因为它们与TimeZone无关。

您不能从中减去一个月,因为它不知道过去一个月中是否有白天过渡。

我知道您要的是不带类型转换的解决方案,但实际上您不能。要正确处理此问题,必须将其转换为具有正确时区的ZonedDateTime。任何不指定时区的解决方案最终都可能导致结果错误的情况。

答案 1 :(得分:2)

您可以使用OffsetDateTime.With,它可以提供LocalDate调节器。您可以使用PlusMinus上操作(LocalDatePeriod,...),从而可以按月指定时间跨度:

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