【问题标题】:Java 8 Date API - Week of year is different for the same day but different timeJava 8 Date API - 同一天的一年中的一周不同但时间不同
【发布时间】:2019-05-30 12:47:48
【问题描述】:

对于我只能假设是时区问题,以下代码会在同一天产生不同的年份值,但时间不同:

注意,代码是用 Kotlin 编写的

示例

fun main(args: Array<String>) {
    
    val middaySundayAfterEpoch = Instant.EPOCH + Duration
        .ZERO
        .plusDays(3)
        .plusHours(12)

    val almostMidnightSundayAfterEpoch = Instant.EPOCH + Duration
        .ZERO
        .plusDays(3)
        .plusHours(23)

    println(getWeekOfYear(middaySundayAfterEpoch))
    println(getWeekOfYear(almostMidnightSundayAfterEpoch))
}

fun getWeekOfYear(instant: Instant): Int {
    val calendar: Calendar = Calendar.getInstance()
    calendar.time = Date.from(instant)

    return calendar.get(Calendar.WEEK_OF_YEAR)
}

结果

1

2

假设

  • 周日,12:00 实际上是周日,日历中的 13:00
  • 星期日,23:00 实际上是星期一,日历中的 00:00

问题

如何修改它以忽略时区,以便两个时间都在同一周发生?

【问题讨论】:

  • 永远不要将糟糕的旧日期时间类 (Calendar & Date) 与现代 java.time 类 (Instant) 混合使用。在 Java 8 及更高版本中采用 JSR 310 后,遗留类被完全取代。仅在与尚未更新到 java.time 的旧代码互操作时转换为/从旧类转换。换句话说,尽可能避免CalendarDate

标签: java kotlin date java-calendar


【解决方案1】:

如果可以避免使用旧版 java.util.Datejava.util.Calendar,则永远不要使用它们,这是众多原因之一。

ZonedDateTime 对象提供了一种获取方法:

instant.atZone(ZoneId.of("UTC")).get(IsoFields.WEEK_OF_WEEK_BASED_YEAR)

编辑:此答案的先前版本使用系统默认时间以及ChronoUnit.ALIGNED_WEEK_OF_YEAR。这将 1 月 1 日至 7 日视为一年中的“第 1 周”,无论 1 月 1 日在特定年份的一周中的哪一天。但是,它将基于ZonedDateTime 的日期部分。

【讨论】:

  • 关于您的编辑,我将如何实现 1 月 5 日至 7 日在第二周的预期行为?
猜你喜欢
  • 2015-08-24
  • 1970-01-01
  • 1970-01-01
  • 2019-11-11
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多