Search code examples
javaiso8601

ISO-8601 week data representation for basic temporal operations


I've got week data in ISO 8601 format. E.g.:

weekA = '2012-W48'
weekB = '2013-W03'

Is there a class in Java that can represent those weeks and supports basic temporal operations? I tried LocalDate.parse("2012-W48",DateTimeFormatter.ISO_WEEK_DATE); but this throws an error because this is a week, not an actual date (i.e. the day in the week is missing). Similar to the LocalDate class, I'd like to be able to do some basic temporal operations such as:

  • weekA.isBefore(weekB) returns true if weekA is before weekB
  • weeksBetween(weekA,weekB) returns the number of weeks between the two week dates, i.e. weekB-weekA in weeks.

Ideally I'd only use standard Java classes (Java >= 11).


Solution

  • Using standard library

    The original solution (check below) was using an external library. The credit for this solution goes to user85421. The idea is to parse the given string into a LocalDate by defaulting the day of the week to day-1.

    public class Main {
        public static void main(String[] args) {
            String strWeekA = "2012-W48";
            String strWeekB = "2013-W03";
    
            DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                    .appendPattern("YYYY-'W'ww")
                    .parseDefaulting(ChronoField.DAY_OF_WEEK, 1)
                    .toFormatter();
    
            LocalDate date1 = LocalDate.parse(strWeekA, dtf);
            LocalDate date2 = LocalDate.parse(strWeekB, dtf);
    
            System.out.println(WEEKS.between(date1, date2));
        }
    }
    

    Output:

    7
    

    Online Demo

    Using an external library (original solution)

    You can use the ThreeTen-Extra library for your requirements.

    You can use YearWeek, and its isBefore and isAfter methods.

    You can use java.time.temporal.ChronoUnit#between to calculate the amount of time between two YearWeek objects. Alternatively, you can use YearWeek#until to get the same result.

    Given below is the Maven dependency for it:

    <dependency>
      <groupId>org.threeten</groupId>
      <artifactId>threeten-extra</artifactId>
      <version>1.7.2</version>
    </dependency>
    

    Demo:

    import org.threeten.extra.YearWeek;
    import static java.time.temporal.ChronoUnit.WEEKS;
    
    public class Main {
        public static void main(String[] args) {
            String strWeekA = "2012-W48";
            String strWeekB = "2013-W03";
            YearWeek weekA = YearWeek.parse(strWeekA);
            YearWeek weekB = YearWeek.parse(strWeekB);
            System.out.println(weekA.isBefore(weekB));
            System.out.println(WEEKS.between(weekA, weekB));
            System.out.println(weekA.until(weekB, WEEKS));
        }
    }
    

    Output:

    true
    7
    7