19

I asked How to detect if a date is within this or next week in Java? but the answers were confusing, so now I think if I can find the past Sunday and the coming Sunday, any day in between is this week, and any day between the coming Sunday and the Sunday after that is next week, am I correct ?

So my new question is : How to get the past Sunday and the coming Sunday in Java ?

Community
  • 1
  • 1
Frank
  • 30,590
  • 58
  • 161
  • 244

9 Answers9

36

java.time

Briefly:

LocalDate.now().with( next( SUNDAY ) ) 

See this code run live at IdeOne.com.

Details

I thought I'd add a Java 8 solution for posterity. Using LocalDate, DayOfWeek, and TemporalAdjuster implementation found in the TemporalAdjusters class.

final LocalDate today = LocalDate.of(2015, 11, 20);
final LocalDate nextSunday = today.with(next(SUNDAY));
final LocalDate thisPastSunday = today.with(previous(SUNDAY));

This approach also works for other temporal classes like ZonedDateTime.

import

As written, it assumes the following static imports:

import java.time.LocalDate;
import static java.time.DayOfWeek.SUNDAY;
import static java.time.temporal.TemporalAdjusters.next;
import static java.time.temporal.TemporalAdjusters.previous;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Bobby Eickhoff
  • 2,585
  • 2
  • 23
  • 22
20

How about this :

Calendar c=Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK,Calendar.SUNDAY);
c.set(Calendar.HOUR_OF_DAY,0);
c.set(Calendar.MINUTE,0);
c.set(Calendar.SECOND,0);
DateFormat df=new SimpleDateFormat("EEE yyyy/MM/dd HH:mm:ss");
System.out.println(df.format(c.getTime()));      // This past Sunday [ May include today ]
c.add(Calendar.DATE,7);
System.out.println(df.format(c.getTime()));      // Next Sunday
c.add(Calendar.DATE,7);
System.out.println(df.format(c.getTime()));      // Sunday after next

The result :

Sun 2010/12/26 00:00:00
Sun 2011/01/02 00:00:00
Sun 2011/01/09 00:00:00

Any day between the first two is this week, anything between the last two is next week.

Frank
  • 30,590
  • 58
  • 161
  • 244
  • 2
    Not the best answer. The java.util.Date and .Calendar classes are so bad that even Sun/Oracle gave up on them. The new [java.time package](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) is now bundled in Java 8 to supplant the old classes. [Joda-Time](http://www.joda.org/joda-time/) inspired java.time and has some superior features. – Basil Bourque Jun 29 '14 at 20:32
  • 4
    If you cannot use Java 8, this solution is beautiful! On Android, we are limited to Java 6 api! – nat101 Jul 01 '14 at 03:08
  • For those seeking a Java 8 solution, I posted an answer below. – Bobby Eickhoff Nov 21 '15 at 04:15
  • 1
    On Samsung phone it give coming sunday instead of past sunday so I subtracted one week. if (c.getTimeInMillis() > today.getTimeInMillis()) { c.set(Calendar.WEEK_OF_MONTH, today.get(Calendar.WEEK_OF_MONTH) - 1); } – Lokesh Tiwari Feb 18 '16 at 15:16
  • 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 Jul 07 '19 at 21:58
4

Without using a better time/date package...

DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
Calendar now = new GregorianCalendar();
Calendar start = new GregorianCalendar(now.get(Calendar.YEAR), 
        now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH) );

while (start.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
    start.add(Calendar.DAY_OF_WEEK, -1);
}

Calendar end = (Calendar) start.clone();
end.add(Calendar.DAY_OF_MONTH, 7);

System.out.println(df.format(now.getTime()) );
System.out.println(df.format(start.getTime()) );
System.out.println(df.format(end.getTime()) );

If today is Sunday, it is considered the start of the time period. If you want a period of this week and next week (as it sounds from your question), you can substitute 14 instead of 7 in the end.add(...) line. The times are set to midnight for comparison of another object falling between start and end.

robert_x44
  • 9,224
  • 1
  • 32
  • 37
4

First, don't use the Date/Time package from Java. There is a much better utility package called Joda-Time - download that and use it.

To determine if your time is in this week, last week, or any week at all, do this:

  1. Create two Interval objects - one for last week and one for this week
  2. Use the contains( long ) method to determine which interval holds the date you are looking for.

There are several cool ways you can create two back to back weeks. You could set up a Duration of one week, find the start time for the first week, and just create two Intervals based on that start time. Feel free to find any other way that works for you - the package has numerous ways to get to what you want.


EDIT:

Joda-Time can be downloaded here, and here is an example of how Joda would do this:

// Get the date today, and then select midnight of the first day of the week
// Joda uses ISO weeks, so all weeks start on Monday.
// If you want to change the time zone, pass a DateTimeZone to the method toDateTimeAtStartOfDay()
DateTime midnightToday = new LocalDate().toDateTimeAtStartOfDay();
DateTime midnightMonday = midnightToday.withDayOfWeek( DateTimeConstants.MONDAY );

// If your week starts on Sunday, you need to subtract one.  Adjust accordingly.
DateTime midnightSunday = midnightMonday.plusDays( -1 );

DateTime midnightNextSunday = midnightSunday.plusDays( 7 );
DateTime midnightSundayAfter = midnightNextSunday.plusDays( 7 );

Interval thisWeek = new Interval( midnightSunday, midnightNextSunday );
Interval nextWeek = new Interval( midnightNextSunday, midnightSundayAfter );

if ( thisWeek.contains( someDate.getTime() )) System.out.println("This week");
if ( nextWeek.contains( someDate.getTime() )) System.out.println("Next week");
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Jonathan B
  • 1,040
  • 6
  • 11
  • 1
    Love joda time, but perhaps this would be better with a code example? ;) – crockpotveggies Jul 25 '12 at 23:21
  • You're right, I should have done exactly that. Edited. – Jonathan B Aug 15 '12 at 23:33
  • 1
    FYI, the [*Joda-Time*](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), advising migration to the [*java.time*](http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jul 07 '19 at 21:58
3

Given bellow next Sunday code and you can easily figure out how to find past Sunday.

private static void nextSunday() throws ParseException 
    {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(new Date());
        int weekday = calendar.get(Calendar.DAY_OF_WEEK);
        int days = Calendar.SUNDAY - weekday;
        if (days < 0)
        {
            days += 7;
        }
        calendar.add(Calendar.DAY_OF_YEAR, days);

        System.out.println(sdf.format(calendar.getTime()));
    }
Soubhab Pathak
  • 619
  • 7
  • 14
  • 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 Jul 07 '19 at 21:57
  • See the modern solution using *java.time* in the [the Answer by Eichhoff](https://stackoverflow.com/a/33839611/642706). – Basil Bourque Jul 07 '19 at 21:57
  • This is still useful on Android for supporting API version < 26 – anemo Apr 26 '20 at 17:35
1

I recently developed Lamma Date which is designed to solve this use case:

Date today = new Date(2014, 7, 1);      // assume today is 2014-07-01
Date previousSunday = today.previousOrSame(DayOfWeek.SUNDAY);   // 2014-06-29
Date nextSunday = today.next(DayOfWeek.SUNDAY);                 // 2014-07-06
Max
  • 2,065
  • 24
  • 20
0

http://download.oracle.com/javase/1.4.2/docs/api/java/util/Date.html

I recommend Calendar.get(Calendar.DAY_OF_WEEK)

Eric
  • 89
  • 1
  • 1
  • 3
  • 4
    I recommend jumping out of the window before using Java's built in Date stuff... ;) – Ivo Wetzel Dec 27 '10 at 02:06
  • Jumping out the window might be a bit radical unless you’re working on the ground floor, but I certainly agree to avoid `Calendar` and it poorly designed friends. Fortunately, after this answer was written, [java.time, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) has come out. I warmly recommend it. – Ole V.V. Oct 22 '18 at 09:29
0

You could try to work with the Calendar.WEEK_OF_YEAR field, which gives you the numeric representation of the week within the current year.

@Test
public void testThisAndNextWeek() throws Exception {
    GregorianCalendar lastWeekCal = new GregorianCalendar(2010,
            Calendar.DECEMBER, 26);
    int lastWeek = lastWeekCal.get(Calendar.WEEK_OF_YEAR);

    GregorianCalendar nextWeekCal = new GregorianCalendar(2011,
            Calendar.JANUARY, 4);
    int nextWeek = nextWeekCal.get(Calendar.WEEK_OF_YEAR);

    GregorianCalendar todayCal = new GregorianCalendar(2010,
            Calendar.DECEMBER, 27);
    int currentWeek = todayCal.get(Calendar.WEEK_OF_YEAR);

    assertTrue(lastWeekCal.before(todayCal));
    assertTrue(nextWeekCal.after(todayCal));
    assertEquals(51, lastWeek);
    assertEquals(52, currentWeek);
    // New Year.. so it's 1
    assertEquals(1, nextWeek);
}
mhaller
  • 14,122
  • 1
  • 42
  • 61
0

My Solution:

    LocalDate date = ...;
    LocalDate newWeekDate = date.plusDays(1);
    while (newWeekDate.getDayOfWeek() != DayOfWeek.SATURDAY &&
           newWeekDate.getDayOfWeek() != DayOfWeek.SUNDAY) {
        newWeekDate = date.plusDays(1);
    }
Guillaume Chevalier
  • 9,613
  • 8
  • 51
  • 79