我正在使用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))
有什么主意,我可以在不进行类型转换的情况下解决这个问题?也许我忽略了文档中的某些内容,但我不这么认为。
答案 0 :(得分:3)
OffsetDateTime
代表本地日期时间,与世界标准时间(UTC)偏移,并带有瞬间。
但是,它未绑定到TimeZone。
由于这个原因,您可以在其中添加“固定”金额,例如秒,分钟和小时,因为它们与TimeZone无关。
您不能从中减去一个月,因为它不知道过去一个月中是否有白天过渡。
我知道您要的是不带类型转换的解决方案,但实际上您不能。要正确处理此问题,必须将其转换为具有正确时区的ZonedDateTime
。任何不指定时区的解决方案最终都可能导致结果错误的情况。
答案 1 :(得分:2)
您可以使用OffsetDateTime.With
,它可以提供LocalDate
调节器。您可以使用Plus
在Minus
上操作(LocalDate
,Period
,...),从而可以按月指定时间跨度:
public OffsetDateTime GetPreviousMonth(OffsetDateTime input)
{
return input.With((LocalDate ld) => ld.Minus(Period.FromMonths(1)));
}