【问题标题】:Why calendar.add() return 31/9/2018为什么 calendar.add() 返回 31/9/2018
【发布时间】:2019-03-05 00:44:33
【问题描述】:

我想从今天(29/9/2018)开始添加 2 天,我使用:

val calendar = Calendar.getInstance()!!
calendar.set(CalendarDay.today().year, CalendarDay.today().month+1, CalendarDay.today().day)
calendar.add(Calendar.DAY_OF_MONTH, 2)

但是当我记录()它时,日期不是 2018 年 1 月 10 日,而是 2018 年 9 月 31 日

【问题讨论】:

  • Calendar.getInstance() 返回已设置当前日期/时间的实例。 sn-p 中的第二行是不必要的,并且很可能是问题所在,因为在这种情况下,将月份加 1 是不正确的;即,CalendarDay.today().month+1 不是您想要的。
  • 我不知道,因为 CalendarDay.today().month 从 0 开始,我为它 +1
  • Calendar 适用于从零开始的月份,这意味着它的 set() 方法也需要从零开始的月份。如果你需要一个“人类可读的”月份数字,你只会加 1。
  • 1 天的差异可能是时区问题,例如当您以 UTC 记录日期并且您在伦敦东部并且对您来说是早上时,它仍然可能是 UTC 日期的前一天。

标签: android kotlin days java.util.calendar


【解决方案1】:

对于您选择使用的旧 API,您可以将其简化为:

val today = Calendar.getInstance()                  // 2018-09-29
today.add(Calendar.DAY_OF_MONTH, 2);                // 2018-10-01

println(SimpleDateFormat().format(today.getTime())) // 2018-10-01

无需设置已包含当前日期的Calendar 实例。

我认为您的输出可能是您误读了,或者在 Android 实现中存在一些奇怪的错误,因为这段代码:

val today = Calendar.getInstance()                   // 2018-09-29

// totally unneccessary:
today.set(today.get(Calendar.YEAR),  
          today.get(Calendar.MONTH), 
          today.get(Calendar.DAY_OF_MONTH))          // 2018-09-29

today.add(Calendar.DAY_OF_MONTH, 2);                 // 2018-10-01

println(SimpleDateFormat().format(today.getTime()))  // 2018-10-01

工作正常,尽管有不必要的步骤(将其设置为已经存在的日期)。如果您像在创建错误日期之前所做的那样在月份中添加一个:

val today = Calendar.getInstance()                  // 2018-09-29

// unnecessary and wrong:
today.set(today.get(Calendar.YEAR), 
          today.get(Calendar.MONTH)+1, 
          today.get(Calendar.DAY_OF_MONTH))         // 2018-10-29

today.add(Calendar.DAY_OF_MONTH, 2);                // 2018-10-31

println(SimpleDateFormat().format(today.getTime())) // 2018-10-31

如果您可以使用较新的 Android 上可用的较新的 JSR 310 API,那就更好了,该解决方案将是(假设您想使用 LocalDate):

val today = LocalDate.now()                           // 2018-09-29
val inTwoDays = today.plusDays(2)                     // 2018-10-01

println(DateTimeFormatter.ISO_DATE.format(inTwoDays)) // 2018-10-01

请阅读java.time 包,了解更多使用日期、日历、时区等的课程。

【讨论】:

  • Android 仅从 API 级别 26 开始支持 java.time,除非有一些我不知道的 Kotlin 魔法。我相信,对于以前的版本,库是必要的。
  • @MikeM。我添加了旧的 API 版本
  • 您可以在旧版 Android 上使用现代 Java 日期和时间 API JSR-310。有一个后端。你当然应该考虑一下,因为Calendar 和朋友们有很多设计问题,而且现代 API 更容易使用。如何?请参阅How to use ThreeTenABP in Android Project 并提供非常详尽的解释。
猜你喜欢
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
  • 2011-01-14
  • 2014-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多