【问题标题】:Is there any different behavior between Calendar#add(Calendar.MONTH, months) and LocalDate#plusMonth(months)?Calendar#add(Calendar.MONTH, months) 和 LocalDate#plusMonth(months) 之间有什么不同的行为吗?
【发布时间】:2020-01-14 00:38:23
【问题描述】:

我正在处理一些遗留代码,其中java.util.Calendar 用于与日期相关的计算(基本上是添加月份)。现在我想在代码中用java.time.LocalDate 替换java.util.Calendar,但我不想改变行为。因此,我一直在寻找一个来源,该来源可以澄清它们对于任何情况下的相同计算都会产生相同的结果,但我找不到任何结果。

特别是我想知道是否有一个日期使它们在以下之间产生不同的结果:

Calendar#add(Calendar.MONTH, months)

LocalDate#plusMonth(months)

我已经测试了一些极端情况(例如与闰年相关的日期),它们似乎产生了相同的结果,但我不能 100% 确定这一点。没有关于这方面的任何官方信息或它们之间的一些已知差异吗?

【问题讨论】:

  • 您咨询过the documentation吗?
  • 是的,但不清楚它们在日期相关计算方面是否 100% 兼容
  • 明确一点:您应该永远使用CalendarDate。这些课程真的很糟糕——JSR 310 被采用是有充分理由的!要与 java.time 尚未更新的遗留代码互操作,您可以轻松地来回转换。查看添加到旧类的新 to…/from… 方法。对于Calendar,转换为GregorianCalendar,然后调用toZonedDateTime。对于java.util.Date,请致电toInstant。换个方向:GregorianCalendar.from( myZonedDateTime )Date.from( myInstant )

标签: java localdate date java.util.calendar


【解决方案1】:

TL;DR

如果:

  • 您确定您的Calendar 确实是GregorianCalendar(迄今为止最常用的子类),并且……
  • 你的日期不会超过 100 年,那么……

...您可以放心地使用LocalDate#plusMonth(months) 而不是Calendar#add(Calendar.MONTH, months)

详情

祝贺您决定从现代 Java 日期和时间 API java.time 中从旧的且设计不佳的 Calendar 类迁移到 LocalDate。这将是对您的代码库的改进。

你是对的,你提到的方法用于相同的目的并且通常工作相同。所以当你从Calendar 迁移到java.time 时,如果你发现LocalDate 是正确的新类,那么你将在之前使用Calendar#add(Calendar.MONTH, months) 的地方使用LocalDate#plusMonth(months)

不同之处包括:

  • Calendar 类是在许多不同的日历系统(GregorianBuddhist 等)中表示日期(和时间)的类的抽象超类,LocalDate 始终在预测的公历中。由于每个日历系统都有自己对月份的定义,因此在公历以外的日历中添加月份数可能会得到与 LocalDate.plusMonths 给出的完全不同的结果。
  • 如果您的日期可以追溯到历史,那么LocalDate 使用proleptic Gregorian calendar 也会产生细微的差别。这意味着它不会将 Julian calendar 用于几个世纪前使用的日期。
  • Calendar.add 修改您调用它的Calendar 对象时,LocalDate.plusMonths 返回一个带有新日期的 LocalDate 对象。
  • 虽然要在日历中倒退,但您需要将负数传递给 Calendar::addLocalDate 有一个方便的 minusMonths 方法,您通常希望使用它来代替 plusMonths(两者都可以,不过)。
  • 每个类可以表示的日期范围不同。我不容易记住每个的最小和最大日期。在Calendar/GregorianCalendar上,可以看到getGreatestMinimum​&getLeastMaximum​等他们的各种方法。对于LocalDate,请参见常量:MAX & MIN

【讨论】:

    猜你喜欢
    • 2019-09-23
    • 2015-04-22
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多