Java 8 Date API - неделя года отличается для одного и того же дня, но в другое время

Поскольку я могу только предположить, что это проблема часового пояса, следующий код выдает разные значения недели в году для одного и того же дня, но в разное время:

Обратите внимание, код написан на 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 в календаре

Вопрос

Как я могу изменить это, чтобы игнорировать часовой пояс, чтобы оба раза происходили на одной и той же неделе?

1 ответ

Решение

Вы никогда не должны использовать наследие java.util.Date а также java.util.Calendar если вы можете избежать их, это одна из многих причин.

ZonedDateTime Объект предоставляет способ получить это:

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

РЕДАКТИРОВАТЬ: предыдущая версия этого ответа использовала системное время по умолчанию, а также ChronoUnit.ALIGNED_WEEK_OF_YEAR, Считается, что 1-7 января является "неделей 1" года, независимо от того, какой день недели 1 января находится в определенном году. Тем не менее, он будет основан на части даты ZonedDateTime,

Другие вопросы по тегам