Tom
Tom

Reputation: 6342

How to calculate the days belonging to an ISO based week number

I have an ISO based week number that is calculated using the following Java 8 LocalDate API

int weekNumOfYear = LocalDate#get(IsoFields.WEEK_OF_WEEK_BASED_YEAR)

Given the year, and the week number (eg, 201927),How could I calculate the start day and end day for this week(201917)?

I am Using Calendar class for this problem, but not sure it is correct(especially, whether is has followed the ISO format)

Update: The following code doesn't work correctly for 201953, there is no 53th week for 2019

@Test
    public void testGetWeekDays() {
        Integer year = 2019;
        Integer week = 27;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();

        //Use ISO format
        cal.setMinimalDaysInFirstWeek(4);

        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.WEEK_OF_YEAR, week);
        cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
        String beginDate = sdf.format(cal.getTime());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        String endDate = sdf.format(cal.getTime());
        System.out.println(beginDate);
        System.out.println(endDate);
    }

Upvotes: 1

Views: 766

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 338730

tl;dr

Given the year, and the week number (eg, 201927),I could I calculate the start day and end day for this week(201917)?

YearWeek              // Represent a particular week of a week-based year.
.of(                  // Factory method, rather than calling `new`. 
    2019 ,            // The number of the desired week-based year ( *not* calendar year! ).
    26                // Week of the year, 1 through 52 or 53. 
)
.atDay(               // Generate a `LocalDate` object for a day within this week.
    DayOfWeek.MONDAY  // Specify the day-of-week.
)                     // Generate a `LocalDate` for the first day of this week.
.plusDays( 6 )        // Generate a `LocalDate` representing the last day of this week. 

ThreeTen-ExtraYearWeek

Working with standard weeks is much easier with the org.threeten.extra.YearWeek class provided in the ThreeTen-Extra project. That project adds functionality to the modern java.time classes built into Java 8 and later.

If you have an ISO 8601 compliant string representing a standard week, parse.

String input = "2019-W27";
YearWeek yw = YearWeek.parse( input);

yw.toString(): 2019-W27

A standard week begins with Monday. The YearWeek object can generate a LocalDate for any day in the week. Specify a day using the DayOfWeek enum.

LocalDate ld = yw.atDay( DayOfWeek.MONDAY);

ld.toString(): 2019-07-01

To get the rest of the week, add a day over and over.

LocalDate nextDay = ld.plusDays( 1 ) ;

ld.toString(): 2019-07-02

To get the end of the week, add six.

LocalDate nextDay = ld.plusDays( 6 ) ;

ld.toString(): 2019-07-07

Or get fancy using Java streams. Generate a stream by calling LocalDate::datesUntil.

Stream < LocalDate > stream = ld.datesUntil ( ld.plusWeeks ( 1 ) );
List < LocalDate > dates = stream.collect ( Collectors.toList () );

dates.toString(): [2019-07-01, 2019-07-02, 2019-07-03, 2019-07-04, 2019-07-05, 2019-07-06, 2019-07-07]

By the way, the standard way to represent a day-of-week within a standard week is to append a hyphen and number 1-7.

2019-W26-1 = Monday

2019-W26-2 = Tuesday

2019-W26-7 = Sunday

Upvotes: 2

Ryuzaki L
Ryuzaki L

Reputation: 40058

You can also use with to get start day and end day of week

System.out.println(localDate.with(DayOfWeek.MONDAY));
System.out.println(localDate.with(DayOfWeek.SUNDAY));

If you want to get start day and end day from week number, then use ISO_WEEK_DATE

LocalDate startDay = LocalDate.parse("2019-W26-1", DateTimeFormatter.ISO_WEEK_DATE);

LocalDate endDay = LocalDate.parse("2019-W26-7", DateTimeFormatter.ISO_WEEK_DATE);

One digit for the day-of-week. The value run from Monday (1) to Sunday (7).

Upvotes: 4

Related Questions