32

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);
dat3450
  • 954
  • 3
  • 13
  • 27
Scorpion
  • 6,831
  • 16
  • 75
  • 123
  • So you want two Sunday dates to be printed? Which two? Can you give further examples of your input and output? – Aman Agnihotri Apr 06 '14 at 06:19
  • Basically I would like to get Week start from Monday to Sunday only. Like this week start on 31-03-2014 and today is the end of the week that is 06-04-2014. I know the month is changed but as its very important for my report I want it like the standard Indian week. Let;s take another example, the last week of April, 2014 starts at 28-04-2014 and end on 04-05-2014. In brief I would like to get Monday to Sunday as a week. – Scorpion Apr 06 '14 at 06:23
  • No 2 Sunday to be printed. – Scorpion Apr 06 '14 at 06:24
  • Alright. So you want one Monday date and the other Sunday date to be printed. What will be the input? Will it be a date between the two dates that you want to be printed? Or you want a program which prints a series of Mondays and Sundays, i.e., Start and End dates? – Aman Agnihotri Apr 06 '14 at 06:26
  • @AmanAgnihotri, the OP said in question title that he wants *current*. I assume that is literal. – merlin2011 Apr 06 '14 at 06:28
  • @merlin2011: Was just making sure. :) – Aman Agnihotri Apr 06 '14 at 06:29
  • Input will be Current date. – Scorpion Apr 06 '14 at 06:41
  • FYI, the terribly troublesome date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Aug 09 '19 at 22:30

7 Answers7

55

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.

ccjmne
  • 9,333
  • 3
  • 47
  • 62
19

Well, looks like you got your answer. Here's an add-on, using java.time in Java 8 and later. (See Tutorial)

import java.time.DayOfWeek;
import java.time.LocalDate;

public class MondaySunday
{
  public static void main(String[] args)
  {
    LocalDate today = LocalDate.now();

    // Go backward to get Monday
    LocalDate monday = today;
    while (monday.getDayOfWeek() != DayOfWeek.MONDAY)
    {
      monday = monday.minusDays(1);
    }

    // Go forward to get Sunday
    LocalDate sunday = today;
    while (sunday.getDayOfWeek() != DayOfWeek.SUNDAY)
    {
      sunday = sunday.plusDays(1);
    }

    System.out.println("Today: " + today);
    System.out.println("Monday of the Week: " + monday);
    System.out.println("Sunday of the Week: " + sunday);
  }
}

Another way of doing it, using temporal adjusters.

import java.time.LocalDate;

import static java.time.DayOfWeek.MONDAY;
import static java.time.DayOfWeek.SUNDAY;
import static java.time.temporal.TemporalAdjusters.nextOrSame;
import static java.time.temporal.TemporalAdjusters.previousOrSame;

public class MondaySunday
{
  public static void main(String[] args)
  {
    LocalDate today = LocalDate.now();

    LocalDate monday = today.with(previousOrSame(MONDAY));
    LocalDate sunday = today.with(nextOrSame(SUNDAY));

    System.out.println("Today: " + today);
    System.out.println("Monday of the Week: " + monday);
    System.out.println("Sunday of the Week: " + sunday);
  }
}
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Aman Agnihotri
  • 2,973
  • 1
  • 18
  • 22
  • 1
    Why not excise the first code example and just present the second code example using `TemporalAdjuster`? I see no advantage to the first. – Basil Bourque Jul 10 '17 at 01:51
  • 1
    I suggest showing the better practice of always specifying a time zone (`ZoneId` object) for `LocalDate.now( z )` rather than rely implicitly on the JVM’s current default time zone that can change at any moment during runtime. – Basil Bourque Jul 10 '17 at 01:55
5

This is what I did to get start and end date for current week.

public static Date getWeekStartDate() {
    Calendar calendar = Calendar.getInstance();
    while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
        calendar.add(Calendar.DATE, -1);
    }
    return calendar.getTime();
}

public static Date getWeekEndDate() {
    Calendar calendar = Calendar.getInstance();
    while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
        calendar.add(Calendar.DATE, 1);
    }
    calendar.add(Calendar.DATE, -1);
    return calendar.getTime();
}
Shrikant
  • 579
  • 1
  • 5
  • 21
  • I do like your code, but in the question, the week starts from Sunday to Monday. With this code, you are displaying the week from Sun-Mond – Nello May 13 '19 at 17:50
1

tl;dr

Use the handy YearWeek class from ThreeTen-Extra library to represent an entire week. Then ask it to determine the date for any day-of-week within that week.

org.threeten.extra.YearWeek          // Handy class representing a standard ISO 8601 week. Class found in the *ThreeTen-Extra* project, led by the same man as led JSR 310 and the *java.time* implementation.
.now(                                // Get the current week as seen in the wall-clock time used by the people of a certain region (a time zone). 
    ZoneId.of( "America/Chicago" ) 
)                                    // Returns a `YearWeek` object.
.atDay(                              // Determine the date for a certain day within that week.
    DayOfWeek.MONDAY                 // Use the `java.time.DayOfWeek` enum to specify which day-of-week.
)                                    // Returns a `LocalDate` object.

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If critical, confirm the zone with your user.

Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety. Ditto for Year & YearMonth.

LocalDate ld = LocalDate.of( 2014 , Month.APRIL , 6 ) ;

YearWeek

Your definition of a week running from Monday to Sunday matches that of the ISO 8601 standard.

Add the ThreeTen-Extra library to your project to access the YearWeek class representing the standard week.

YearWeek week = YearWeek.from( ld ) ;  // Determine the week of a certain date.

Or get today's week.

YearWeek week = YearWeek.now( z ) ;

Get the date for any day of the week. Specify which day by using DayOfWeek enum.

LocalDate firstOfWeek = week.atDay( DayOfWeek.MONDAY ) ;
LocalDate lastOfWeek = week.atDay( DayOfWeek.SUNDAY ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

I used below method to check if a given date falls in current week

public boolean isDateInCurrentWeek(Date date) 
{
        Date currentWeekStart, currentWeekEnd;

        Calendar currentCalendar = Calendar.getInstance();
        currentCalendar.setFirstDayOfWeek(Calendar.MONDAY);
        while(currentCalendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY)
        {
            currentCalendar.add(Calendar.DATE,-1);//go one day before
        }
        currentWeekStart = currentCalendar.getTime();

        currentCalendar.add(Calendar.DATE, 6); //add 6 days after Monday
        currentWeekEnd = currentCalendar.getTime();

        Calendar targetCalendar = Calendar.getInstance();
        targetCalendar.setFirstDayOfWeek(Calendar.MONDAY);
        targetCalendar.setTime(date);


        Calendar tempCal = Calendar.getInstance();
        tempCal.setTime(currentWeekStart);

        boolean result = false;
        while(!(tempCal.getTime().after(currentWeekEnd)))
        {
            if(tempCal.get(Calendar.DAY_OF_YEAR)==targetCalendar.get(Calendar.DAY_OF_YEAR))
            {
                result=true;
                break;
            }
            tempCal.add(Calendar.DATE,1);//advance date by 1
        }

        return result;
    }
Dev
  • 817
  • 10
  • 16
  • You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes. Another problem: Stack Overflow is meant to be more than a code snippet library. Provide some discussion about how your Answer is different from others. Explain how your code example works. – Basil Bourque Jul 09 '17 at 20:44
0
Calendar privCalendar = Calendar.getInstance();
Date fdow, ldow;
int dayofWeek = privCalendar.get ( Calendar.DAY_OF_WEEK );
Date fdow, ldow;

                    if( dayofWeek == Calendar.SUNDAY ) {

                        privCalendar.add ( Calendar.DATE, -1 * (dayofWeek -
                                Calendar.MONDAY ) - 7 );

                        fdow = privCalendar.getTime();

                        privCalendar.add( Calendar.DATE, 6 );

                        ldow = privCalendar.getTime();
                    } else {

                        privCalendar.add ( Calendar.DATE, -1 * (dayofWeek -
                                Calendar.MONDAY ) );

                        fdow = privCalendar.getTime();

                        privCalendar.add( Calendar.DATE, 6 );

                        ldow = privCalendar.getTime();
                    }
K1TS
  • 1
  • 1
  • 1
  • You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes. Another problem: Stack Overflow is meant to be more than a code snippet library. Provide some discussion about how your Answer is different from others. Explain how your code example works. – Basil Bourque Jul 09 '17 at 16:17
  • Well, by default, week starts from Sunday to Monday. So, if I choose Calendar.Sunday, it is belong to next week. And if i try to get Calendar.Monday, it shows me Monday of the next week. In order to fix this mistake i substract from Monday 7 days. – K1TS Jul 10 '17 at 01:46
  • Edit your Answer to provide more discussion. Another major problem with your code is ignoring the crucial issue of time zone. And, really, it is time to give up on the bloody mess that is the `Calendar` class and learn java.time. This work is *so* much easier with java.time. See the [correct Answer](https://stackoverflow.com/a/22890888/642706) by Aman Agnihotri. – Basil Bourque Jul 10 '17 at 01:49
0
/**
 * Get the date of the first day in the week of the provided date
 * @param date A date in the interested week
 * @return The date of the first week day
 */
public static Date getWeekStartDate(Date date){
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.set(Calendar.DAY_OF_WEEK, getFirstWeekDay());
    return cal.getTime();
}

/**
 * Get the date of the last day in the week of the provided date
 * @param date A date in the interested week
 * @return The date of the last week day
 */
public static Date getWeekEndDate(Date date){
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.add(Calendar.DATE, 6);// last day of week
    return cal.getTime();
}

Date now = new Date(); // any date
Date weekStartDate = getWeekStartDate(now);
Date weekEndDate = getWeekEndDate(now);

// if you don't want the end date to be in the future
if(weekEndDate.after(now))
    weekEndDate = now;
Islam Assi
  • 991
  • 1
  • 13
  • 18
  • FYI, the terribly troublesome date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Aug 09 '19 at 22:30
  • 1
    This code neglects to account for time zones explicitly. – Basil Bourque Aug 09 '19 at 22:31