Calendar#add(Calendar.MONTH, months) 和 LocalDate#plusMonth(months) 之间有什么不同的行为吗?
Is there any different behavior between Calendar#add(Calendar.MONTH, months) and LocalDate#plusMonth(months)?
我正在处理一些遗留代码,其中 java.util.Calendar
用于与日期相关的计算(基本上是添加月份)。现在我想在代码中用 java.time.LocalDate
替换 java.util.Calendar
但我不想改变行为。所以,我一直在寻找一个来源,它澄清了它们对任何情况下的相同计算都会产生相同的结果,但我找不到任何来源。
特别是我想知道是否有一个日期使它们产生不同的结果:
Calendar#add(Calendar.MONTH, months)
和
LocalDate#plusMonth(months)
我测试了一些极端情况(例如与闰年相关的日期),它们似乎产生了相同的结果,但我不能 100% 确定这一点。是否有关于此的任何官方信息或它们之间的一些已知差异?
TL;DR
如果:
- 你确定你的
Calendar
is really a GregorianCalendar
(目前最常用的subclass),以及...
- 你的约会不会超过 100 年前,那么……
…你可以安全地使用LocalDate#plusMonth(months)
instead of Calendar#add(Calendar.MONTH, months)
.
详情
祝贺您决定从旧的和设计不佳的 Calendar
class 迁移到 java.time 的 LocalDate
,现代的 Java 日期和时间API。这将改进您的代码库。
你是对的,你说的方法是同一个目的,大体上是一样的。因此,当您从 Calendar
迁移到 java.time 时,如果您发现 LocalDate
是正确的新 class 使用,那么您将在您使用的地方使用 LocalDate#plusMonth(months)
Calendar#add(Calendar.MONTH, months)
之前。
差异包括:
-
Calendar
class is an abstract superclass for classes representing dates (and times) in many different calendar systems (Gregorian, Buddhist 及更多),LocalDate
总是在公历中。由于每个日历系统都有自己对月份的定义,因此在公历以外的日历中添加月份数可能会得出与 LocalDate.plusMonths
给出的结果截然不同的结果。
- 如果您的日期可以追溯到历史上,那么
LocalDate
将 proleptic Gregorian calendar. This means that it doesn’t use the Julian calendar 用于几个世纪前使用的日期也会有细微差别。
- 虽然
Calendar.add
修改了您调用它的 Calendar
对象,但 LocalDate.plusMonths
returns a new LocalDate
具有新日期的对象。
- 虽然要在日历中倒退,您需要将负数的月份传递给
Calendar::add
, LocalDate
has a convenient minusMonths
方法,您通常希望使用该方法而不是 plusMonths
(尽管两者都有效)。
- 每个class可以表示的日期范围是不同的。我不太记得每个日期的最小和最大日期。在
Calendar
/GregorianCalendar
上,查看他们的各种方法,例如 getGreatestMinimum
和 getLeastMaximum
。对于 LocalDate
,请参阅常量:MAX
& MIN
。
我正在处理一些遗留代码,其中 java.util.Calendar
用于与日期相关的计算(基本上是添加月份)。现在我想在代码中用 java.time.LocalDate
替换 java.util.Calendar
但我不想改变行为。所以,我一直在寻找一个来源,它澄清了它们对任何情况下的相同计算都会产生相同的结果,但我找不到任何来源。
特别是我想知道是否有一个日期使它们产生不同的结果:
Calendar#add(Calendar.MONTH, months)
和
LocalDate#plusMonth(months)
我测试了一些极端情况(例如与闰年相关的日期),它们似乎产生了相同的结果,但我不能 100% 确定这一点。是否有关于此的任何官方信息或它们之间的一些已知差异?
TL;DR
如果:
- 你确定你的
Calendar
is really aGregorianCalendar
(目前最常用的subclass),以及... - 你的约会不会超过 100 年前,那么……
…你可以安全地使用LocalDate#plusMonth(months)
instead of Calendar#add(Calendar.MONTH, months)
.
详情
祝贺您决定从旧的和设计不佳的 Calendar
class 迁移到 java.time 的 LocalDate
,现代的 Java 日期和时间API。这将改进您的代码库。
你是对的,你说的方法是同一个目的,大体上是一样的。因此,当您从 Calendar
迁移到 java.time 时,如果您发现 LocalDate
是正确的新 class 使用,那么您将在您使用的地方使用 LocalDate#plusMonth(months)
Calendar#add(Calendar.MONTH, months)
之前。
差异包括:
-
Calendar
class is an abstract superclass for classes representing dates (and times) in many different calendar systems (Gregorian, Buddhist 及更多),LocalDate
总是在公历中。由于每个日历系统都有自己对月份的定义,因此在公历以外的日历中添加月份数可能会得出与LocalDate.plusMonths
给出的结果截然不同的结果。 - 如果您的日期可以追溯到历史上,那么
LocalDate
将 proleptic Gregorian calendar. This means that it doesn’t use the Julian calendar 用于几个世纪前使用的日期也会有细微差别。 - 虽然
Calendar.add
修改了您调用它的Calendar
对象,但LocalDate.plusMonths
returns a newLocalDate
具有新日期的对象。 - 虽然要在日历中倒退,您需要将负数的月份传递给
Calendar::add
,LocalDate
has a convenientminusMonths
方法,您通常希望使用该方法而不是plusMonths
(尽管两者都有效)。 - 每个class可以表示的日期范围是不同的。我不太记得每个日期的最小和最大日期。在
Calendar
/GregorianCalendar
上,查看他们的各种方法,例如getGreatestMinimum
和getLeastMaximum
。对于LocalDate
,请参阅常量:MAX
&MIN
。