Java Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Introduction

In this article, we'll study several options that we can use in Java to get the week number for a given date. We'll start by looking at a few options for legacy code using classes prior to Java 8. Afterward, we'll take a look at the newer Date Time API in the java.time package that was introduced in Java 8.

2. Before Java 8

Prior to Java 8, date and time calculations were performed mainly using the Date and Calendar classes. Typically we create a Calendar, and then it is possible to extract the information we need from it by using different constants.

2.1. Get Week Number Using Calendar Fields

Let's look at our first example:

Calendar calendar = Calendar.getInstance(locale); 
calendar.set(year, month, day); 
int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);

We simply create a Calendar instance for the given Locale and set the year, month, and day, and finally, we get the WEEK_OF_YEAR field from the calendar object. This will return the week number within the current year.

Now, let's take a look at how to invoke this method from one of our unit tests:

@Test
public void givenDateUsingFieldsAndLocaleItaly_whenGetWeekNumber_thenWeekIsReturnedCorrectly() {
    Calendar calendar = Calendar.getInstance(Locale.ITALY);
    calendar.set(2020, 10, 22);

    assertEquals(47, calendar.get(Calendar.WEEK_OF_YEAR));
}

We need to be careful when adopting this approach, as the month field in the Calendar class is zero-based. This means if we want to specify December, then we need to use the number 11, which can often lead to confusion.

2.2. Get Week Number Using Locale Setups

In this penultimate example, we'll take a look at what the effect of applying some additional settings to our Calendar can have:

Calendar calendar = Calendar.getInstance();
calendar.setFirstDayOfWeek(firstDayOfWeek);
calendar.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek);
calendar.set(year, month, day);

int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);

The Calendar class defines two methods:

  • setFirstDayOfWeek
  • setMinimalDaysInFirstWeek

These methods have an impact on how we calculate the week number. Normally, both these values are taken from the Locale when creating the Calendar. But it is also possible to set the first day in the week and the minimal days in the first week of the year manually.

2.3. Locale Differences

Locale plays an important role in how the week number is calculated:

@Test
public void givenDateUsingFieldsAndLocaleCanada_whenGetWeekNumber_thenWeekIsReturnedCorrectly() {
    Calendar calendar = Calendar.getInstance(Locale.CANADA);
    calendar.set(2020, 10, 22);

    assertEquals(48, calendar.get(Calendar.WEEK_OF_YEAR));
}

In this unit test, we've only changed the locale of the Calendar to use Locale.CANADA instead of Locale.ITALY and now the week number returned is 48 instead of 47.

Both results are correct. As mentioned previously, this happens because each Locale has different settings for the setFirstDayOfWeek and setMinimalDaysInFirstWeek methods.

3. Java 8 Date Time API

Java 8 introduced new APIs for Date and Time to address the shortcomings of the older java.util.Date and java.util.Calendar.

In this section, we'll take a look at some options for getting the week number from the date using this newer API.

3.1. Get Week Number Using the Numerical Values

Likewise, as we saw before with Calendar, we can also pass year, month, and day values directly into LocalDate:

LocalDate date = LocalDate.of(year, month, day);
int weekOfYear = date.get(WeekFields.of(locale).weekOfYear());

The benefit over our pre-Java 8 examples is that we don't have the problem of the month field being zero-based.

3.2. Get Week Number Using Chronofield

In this final example we'll see how to use the ChronoField enumeration, which implements the TemporalField interface:

LocalDate date = LocalDate.of(year, month, day);
int weekOfYear = date.get(ChronoField.ALIGNED_WEEK_OF_YEAR);

This example is similar to using the Calendar.WEEK_OF_YEAR int constant that we saw previously, but using ChronoField.ALIGNED_WEEK_OF_YEAR.

4. Conclusion

In this quick tutorial, we illustrated several ways of getting the week number from a date using plain Java.

As always, the full source code of the article is available over on GitHub.

Java bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
guest
0 Comments
Inline Feedbacks
View all comments