javakotlindatejava-calendar

Java 8 Date API - Week of year is different for the same day but different time


For what I can only assume is a timezone issue, the following code yields different week of year values for the same day, but different times:

Note, the code is written in Kotlin

Example

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)
}

Results

1

2

Assumptions

Question

How do I modify this to ignore the time zone, so that both times occur in the same week?


Solution

  • You should never use the legacy java.util.Date and java.util.Calendar if you can possibly avoid them, this being one of many reasons.

    The ZonedDateTime object provides a way to get this:

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

    EDIT: A previous version of this answer used the system default time, as well as ChronoUnit.ALIGNED_WEEK_OF_YEAR. This considers 1-7 January to be "week 1" of the year, regardless of on which day of the week 1 January lies in a particular year. However, it will be based on the date part of the ZonedDateTime.