为什么我不能向 OffsetDateTime 添加月份?
Why can't I add months to OffsetDateTime?
我正在使用 NodaTime 管理 .Net Core WebApi 中的日期和时区。库中的一种类型是 OffsetDateTime,它与 .Net 框架中的 DateTimeOffset 非常相似。我到处都使用它以明确和透明的方式操作日期,因为日期有时会进入系统时区和用户时区。
我需要在某个时间点将一个月添加到某个日期,但我无法将一个月添加到 OffsetDateTime 对象,我所能做的就是添加到小时或称为 Duration 的类型,即日历-独立的。如果它是我能理解的 Instant 类型,因为 Instant 以一种非常抽象的方式表示一个时间点,而不是 OffsetDateTime。 OffsetDateTime 甚至有一个 "Calendar" 属性 这确实表明它绑定到一个日历系统,它应该允许你像我想做的那样做算术,而不必通过类型转换等。
最重要的是,DateTimeOffset(来自 .net 框架)允许您添加月份,但我希望保持一致并在所有地方使用相同的类型。
长话短说,我做不到:
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))
知道如何在不进行类型转换的情况下解决这个问题吗?也许我忽略了文档中的某些内容,但我不这么认为。
您可以使用 OffsetDateTime.With
,它可以让您提供一个 LocalDate
调节器。您可以使用 Period
在 LocalDate
上操作 (Plus
、Minus
、...),它允许您以月为单位指定时间跨度:
public OffsetDateTime GetPreviousMonth(OffsetDateTime input)
{
return input.With((LocalDate ld) => ld.Minus(Period.FromMonths(1)));
}
OffsetDateTime
表示与 UTC 有偏差的本地日期时间,和 是 Instant。
但是,它没有绑定到时区。
因此,您可以从中添加一个“固定”数量,例如秒、分钟和小时,因为它们不依赖于时区。
您不能从中减去一个月,因为它不知道过去一个月是否有日光转换。
我知道您要求的是不进行类型转换的解决方案,但实际上您做不到。要正确处理此问题,您必须将其转换为具有正确时区的 ZonedDateTime
。任何未指定时区的解决方案最终都可能会遇到结果错误的情况。
你可以直接使用OffsetDateTime
,但是你应该使用一些类似now()
的方法。
然后可以加减D,M,Y,H,M,S等等
OffsetDateTime.now().minusDays(5).
format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"))
或
OffsetDateTime.now(ZoneOffset.UTC).plusMonths(month).
format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"))
我正在使用 NodaTime 管理 .Net Core WebApi 中的日期和时区。库中的一种类型是 OffsetDateTime,它与 .Net 框架中的 DateTimeOffset 非常相似。我到处都使用它以明确和透明的方式操作日期,因为日期有时会进入系统时区和用户时区。
我需要在某个时间点将一个月添加到某个日期,但我无法将一个月添加到 OffsetDateTime 对象,我所能做的就是添加到小时或称为 Duration 的类型,即日历-独立的。如果它是我能理解的 Instant 类型,因为 Instant 以一种非常抽象的方式表示一个时间点,而不是 OffsetDateTime。 OffsetDateTime 甚至有一个 "Calendar" 属性 这确实表明它绑定到一个日历系统,它应该允许你像我想做的那样做算术,而不必通过类型转换等。
最重要的是,DateTimeOffset(来自 .net 框架)允许您添加月份,但我希望保持一致并在所有地方使用相同的类型。
长话短说,我做不到:
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))
知道如何在不进行类型转换的情况下解决这个问题吗?也许我忽略了文档中的某些内容,但我不这么认为。
您可以使用 OffsetDateTime.With
,它可以让您提供一个 LocalDate
调节器。您可以使用 Period
在 LocalDate
上操作 (Plus
、Minus
、...),它允许您以月为单位指定时间跨度:
public OffsetDateTime GetPreviousMonth(OffsetDateTime input)
{
return input.With((LocalDate ld) => ld.Minus(Period.FromMonths(1)));
}
OffsetDateTime
表示与 UTC 有偏差的本地日期时间,和 是 Instant。
但是,它没有绑定到时区。
因此,您可以从中添加一个“固定”数量,例如秒、分钟和小时,因为它们不依赖于时区。
您不能从中减去一个月,因为它不知道过去一个月是否有日光转换。
我知道您要求的是不进行类型转换的解决方案,但实际上您做不到。要正确处理此问题,您必须将其转换为具有正确时区的 ZonedDateTime
。任何未指定时区的解决方案最终都可能会遇到结果错误的情况。
你可以直接使用OffsetDateTime
,但是你应该使用一些类似now()
的方法。
然后可以加减D,M,Y,H,M,S等等
OffsetDateTime.now().minusDays(5).
format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"))
或
OffsetDateTime.now(ZoneOffset.UTC).plusMonths(month).
format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"))