以下代码:
Instant inFourWeeks = Instant.now().plus(4L, ChronoUnit.WEEKS);
引发异常:
java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Weeks
为什么不支持数周?我理解为什么不支持数月和数月,因为它们使用较小单位的持续时间可能会有所不同。但是 week 的持续时间(7天)是固定的,我可以这样写:
Instant inFourWeeks = Instant.now().plus(4L * 7L, ChronoUnit.DAYS);
答案 0 :(得分:5)
每周7天抛出UnsupportedTemporalTypeException
并不普遍且持续。不同的日历系统可能会有所不同。例如,查看每周使用6天的Akan日历系统。
答案 1 :(得分:3)
ChronoUnit.WEEKS
可以在ISO日历以外的其他日历系统中使用数周。这样的几周可能长达6或10天。因此,尽管可以说Instant
支持几天是合理的,但对于几周来说却并非如此。
从文档中:
代表一周概念的单位。对于ISO日历 系统,等于7天。
与其他日历系统一起使用时,必须与 天数的整数。
显然,WEEKS
通常不采用ISO日历系统,也可以与其他日历一起使用。
参数的另一部分是Instant
不采用一个日历系统,但也可以与其他日历系统一起使用。 (例如,ZonedDateTime
相反,假设ISO-8601日历系统也支持星期。)
PS,我想反问一下:为什么Instant
支持几天?一天可能是23、23.5、24、24.5或25小时,并且历史上的其他时间也是如此。
答案 2 :(得分:2)
Instant
类处理绝对时间,并尝试避免与不同日历系统,地区和文化 group 和解释的方式有关的所有歧义。
某些日历系统具有不同的星期长度,一些具有不同的月分组,具有从不同日期开始的年份,并以不同的方式调整leap年和leap秒(如果有的话,例如朱利安日历的情况)经历了太多的from年,并从本应与之同步的“物理”现象(例如季节,至高无上和春分)中消失了。
为避免这些问题,Instant
类允许您使用更精确定义和标准化的单位,例如秒,分钟,小时和天。
在Java发生的最后1000秒中,Le秒是“平滑的”,因此从程序员的角度来看,它们不存在。 (计算机时钟仍然不够准确,需要经常与NTP同步。)
假定1天为24 SI小时,其中1 SI小时定义为60 SI分钟,1 SI分钟定义为60 SI秒,1 SI秒为9,192,631,770 Caesium-133的辐射时间。 24小时实际上是平均太阳日(两次连续的“正午”之间经过的时间),因为由于椭圆轨道,太阳本身的轨道以及轨道速度的变化,每个太阳日可能会更长或更短。您必须要注意的一件事是夏令时。在那些特殊的日子里,一天是25个小时还是23个小时,具体取决于时钟的移动方向。但是,Instant
类对此并不在意,如果您在夏时制边界上增加1天,它仍将移动24小时。它不包含任何时区或地区信息(DST特定于国家/地区)。
答案 3 :(得分:1)
如果您查看plus(long, TemporalUnit)
的代码,则该代码不支持WEEK,
@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);
}
从代码中可以明显看出,结果是通过乘以秒的秒表示来计算的,因此,根据javadoc,周/月/年不能用秒来逻辑一致地表示,因为它们不是通用的竞争内容。>
答案 4 :(得分:1)
其他答案正确。我要补充一点说明。
Instant
是基本构建块 Instant
类是 java.time 类中的基本构建块。它代表一个时刻,是时间轴上的一个点。在内部,它仅是自UTC 1970年第一时刻的纪元参考以来的整数秒数。因此,该类几乎没有功能。
在许多可能的日历系统中的任何一个中,此构造块都可用于跟踪时刻。合理使用Instant
并将其视为日期,星期,月份等,取决于特定日历系统的定义。日历系统可以定义一周中的任何天数,或一年中的任何月数,依此类推,或者甚至可能没有这样的概念,例如或一个月。
最明显的日历系统是在整个西方和世界其他地区使用的现代ISO 8601。 OffsetDateTime
和ZonedDateTime
类建立在Instant
之上,构成了此ISO日历系统的关键部分。这些类与Instant
捆绑在一起只是因为它们被许多Java程序员普遍使用。但是它们绝不是唯一的日历系统。
请查看以下各种日历系统的java.time.chrono
软件包:
HijrahChronology
IsoChronology
JapaneseChronology
MinguoChronology
ThaiBuddhistChronology
ThreeTen-Extra项目为 java.time 类提供了附加功能。这包括更多的日历系统:
AccountingChronology
BritishCutoverChronology
CopticChronology
DiscordianChronology
InternationalFixedChronology
JulianChronology
PaxChronology
Symmetry010Chronology
Symmetry454Chronology
可能我还不知道来自第三方的更多信息。