首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么Instant不支持ChronoUnit.YEARS操作?

为什么Instant不支持ChronoUnit.YEARS操作?
EN

Stack Overflow用户
提问于 2016-10-07 09:15:21
回答 2查看 18K关注 0票数 51

这对我来说是出乎意料的:

代码语言:javascript
运行
复制
> Clock clock = Clock.systemUTC();

> Instant.now(clock).minus(3, ChronoUnit.DAYS);
java.time.Instant res4 = 2016-10-04T00:57:20.840Z

> Instant.now(clock).minus(3, ChronoUnit.YEARS);
java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Years

作为一种解决方法,我必须这样做:

代码语言:javascript
运行
复制
> Instant.now(clock).atOffset(ZoneOffset.UTC).minus(3, ChronoUnit.YEARS).toInstant();
java.time.Instant res11 = 2013-10-07T01:02:56.361Z

我很好奇为什么Instant不支持年份。开发人员就这么放弃了吗?

(在我的实际代码中,我试图减去一个Period.ofYears(3),但引用的Instant方法才是最后被调用的方法)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-13 17:27:50

我正在尝试一些在我看来非常合乎逻辑的东西。

下面是minus(...)中使用的plus(long, TemporalUnit)方法的代码:

代码语言:javascript
运行
复制
@Override
public Instant plus(long amountToAdd, TemporalUnit unit) {
    if (unit instanceof ChronoUnit) {
        switch ((ChronoUnit) unit) {
            case NANOS: return plusNanos(amountToAdd);
            case MICROS: return plus(amountToAdd / 1000_000, (amountToAdd % 1000_000) * 1000);
            case MILLIS: return plusMillis(amountToAdd);
            case SECONDS: return plusSeconds(amountToAdd);
            case MINUTES: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_MINUTE));
            case HOURS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_HOUR));
            case HALF_DAYS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_DAY / 2));
            case DAYS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_DAY));
        }
        throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
    }
    return unit.addTo(this, amountToAdd);
}

我们可以看到,结果是通过单位的秒表示来计算的,由于显而易见的原因,一年不能逻辑地和一致地用秒来表示。

添加

我可以看到另一个显而易见的原因:上面方法中使用的常量来自java.time.LocalTime。常量仅定义到天数的单位。未定义上述天数的常量(在LocalDateLocalDateTime中均未定义)。

票数 36
EN

Stack Overflow用户

发布于 2019-07-12 22:37:25

我猜这是因为Instant不包含时区信息。这意味着同一个Instant可以被解释为不同时区的不同日期-时间值。假设我们有Instant,在UTC+2时区表示为2016.01.01 00:30:00。同样的Instant表示2015.12.31 23:30:00在UTC+1时区。2016是一个闰年,它的长度是366天,所以为了得到Instant减1年,我们必须从它中减去366天。但是2015年不是闰年,它的长度是365天,所以我们必须从Instant中减去365天。这种模糊性导致Instant不支持ChronoUnit.YEARS。类似的问题导致Instant不支持ChronoUnit.MONTHS。可能是缺少DST信息导致Instant不支持ChronoUnit.WEEKS。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39907925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档