Get current week start and end date in Java - (MONDAY TO SUNDAY)

Scorpion picture Scorpion · Apr 6, 2014 · Viewed 59.9k times · Source

Today is 2014-04-06 (Sunday).

The output I get from using the code below is:

Start Date = 2014-04-07
End Date = 2014-04-13

This is the output I would like to get instead:

Start Date = 2014-03-31
End Date = 2014-04-06

How can I achieve this?

This is the code I have completed so far:

// Get calendar set to current date and time
Calendar c = GregorianCalendar.getInstance();

System.out.println("Current week = " + Calendar.DAY_OF_WEEK);

// Set the calendar to monday of the current week
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println("Current week = " + Calendar.DAY_OF_WEEK);

// Print dates of the current week starting on Monday
DateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
String startDate = "", endDate = "";

startDate = df.format(c.getTime());
c.add(Calendar.DATE, 6);
endDate = df.format(c.getTime());

System.out.println("Start Date = " + startDate);
System.out.println("End Date = " + endDate);

Answer

ccjmne picture ccjmne · Apr 6, 2014

Updated answer using Java 8

Using Java 8 and keeping the same principle as before (the first day of the week depends on your Locale), you should consider using the following:

Obtain the first and last DayOfWeek for a specific Locale

final DayOfWeek firstDayOfWeek = WeekFields.of(locale).getFirstDayOfWeek();
final DayOfWeek lastDayOfWeek = DayOfWeek.of(((firstDayOfWeek.getValue() + 5) % DayOfWeek.values().length) + 1);

Query for this week's first and last day

LocalDate.now(/* tz */).with(TemporalAdjusters.previousOrSame(firstDayOfWeek)); // first day
LocalDate.now(/* tz */).with(TemporalAdjusters.nextOrSame(lastDayOfWeek));      // last day

Demonstration

Consider the following class:

private static class ThisLocalizedWeek {

    // Try and always specify the time zone you're working with
    private final static ZoneId TZ = ZoneId.of("Pacific/Auckland");

    private final Locale locale;
    private final DayOfWeek firstDayOfWeek;
    private final DayOfWeek lastDayOfWeek;

    public ThisLocalizedWeek(final Locale locale) {
        this.locale = locale;
        this.firstDayOfWeek = WeekFields.of(locale).getFirstDayOfWeek();
        this.lastDayOfWeek = DayOfWeek.of(((this.firstDayOfWeek.getValue() + 5) % DayOfWeek.values().length) + 1);
    }

    public LocalDate getFirstDay() {
        return LocalDate.now(TZ).with(TemporalAdjusters.previousOrSame(this.firstDayOfWeek));
    }

    public LocalDate getLastDay() {
        return LocalDate.now(TZ).with(TemporalAdjusters.nextOrSame(this.lastDayOfWeek));
    }

    @Override
    public String toString() {
        return String.format(   "The %s week starts on %s and ends on %s",
                                this.locale.getDisplayName(),
                                this.firstDayOfWeek,
                                this.lastDayOfWeek);
    }
}

We can demonstrate its usage as follows:

final ThisLocalizedWeek usWeek = new ThisLocalizedWeek(Locale.US);
System.out.println(usWeek);
// The English (United States) week starts on SUNDAY and ends on SATURDAY
System.out.println(usWeek.getFirstDay()); // 2018-01-14
System.out.println(usWeek.getLastDay());  // 2018-01-20

final ThisLocalizedWeek frenchWeek = new ThisLocalizedWeek(Locale.FRANCE);
System.out.println(frenchWeek);
// The French (France) week starts on MONDAY and ends on SUNDAY
System.out.println(frenchWeek.getFirstDay()); // 2018-01-15
System.out.println(frenchWeek.getLastDay());  // 2018-01-21

Original Java 7 answer (outdated)

Simply use:

c.setFirstDayOfWeek(Calendar.MONDAY);

Explanation:

Right now, your first day of week is set on Calendar.SUNDAY. This is a setting that depends on your Locale.

Thus, a better alternative would be to initialise your Calendar specifying the Locale you're interested in.
For example:

Calendar c = GregorianCalendar.getInstance(Locale.US);

... would give you your current output, while:

Calendar c = GregorianCalendar.getInstance(Locale.FRANCE);

... would give you your expected output.