Frank
Frank

Reputation: 31086

How to detect if a date is within this or next week in java?

If I have a date of an event, such as 2011-01-03, how to detect if it is within this or next week in java ? Any sample code ?

Edit :

I thought it was a simple question, it turned out more complex than I thought, what I meat this week is : from this past Sun to this Sat, next week is from next Sun to the Sat after that.

Upvotes: 8

Views: 11173

Answers (9)

Achala Dissanayake
Achala Dissanayake

Reputation: 860

This is what worked for me in Java 8

import java.time.LocalDate;

LocalDate today = LocalDate.now();
LocalDate twoWeeksBefore = today.minusWeeks(2);
LocalDate checkDate = someObject.getSomeDate();

if(checkDate.compareTo(twoWeeksBefore) > 0) {
    // do something if checkDate is within last two weeks
} else {
    // do something if checkDate is on or before last two weeks
}

Upvotes: 0

Meno Hochschild
Meno Hochschild

Reputation: 44061

Most answers here do not satisfy me. They either use the outdated Calendar-API (excusable in old answers given in times before Java 8, and it is hence not fair to criticize such answers), or they are even partially wrong or unnecessarily complex. For example, the most upvoted answer by Jon Skeet suggests to determine the first day of week by the Joda-expression new LocalDate().withDayOfWeek(DateTimeConstants.SUNDAY). But such code uses the ISO-definition of a week starting on Monday with the consequence that if the current date is not on Sunday the code would produce next Sunday and not previous Sunday as desired by the OP. Joda-Time is incapable of handling non-ISO weeks.

Another minor flaw of other answers is not to care about if the current AND NEXT week contains a given date - as requested by the OP. So here my improved suggestion in modern Java:

LocalDate today = LocalDate.now(); // involves the system time zone and clock of system
LocalDate startOfCurrentWeek =
  today.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
LocalDate endOfNextWeek =
  startOfCurrentWeek.plusDays(13);

LocalDate event = LocalDate.of(2011, 1, 3); // input of example given by OP

boolean matchingResult =
  !(event.isBefore(startOfCurrentWeek) || event.isAfter(endOfNextWeek));

Side note: The question has inspired me to add a small enhancement to the class DateInterval in my library Time4J how to determine the current calendar week in a very generic way.

Upvotes: 3

Basil Bourque
Basil Bourque

Reputation: 338276

tl;dr

Testing a pair of LocalDate objects by using org.threeten.extra.LocalDateRange class with a TemporalAdjuster named ta that determines the first day of the week.

        LocalDateRange.of( 
            localDate1.with( ta ) , 
            localDate1.with( ta ).plusWeeks( 1 ) 
        )
        .contains( 
            localDate2 
        )

ThreeTen-Extra

The ThreeTen-Extra project adds additional functionality to the java.time classes built into Java (defined by JSR 310).

Among the added classes is LocalDateRange. This class represents a span-of-time attached to the timeline. In other words, a pair of LocalDate objects. This class offers handy methods for comparing, such as overlaps, contains, and abuts. Here we need equals.

Define a method where you pass your two dates plus the first day of the week (a DayOfWeek enum object).

We use a TemporalAdjuster found in the TemporalAdjusters class to determine the date of the first day of the week. Then add a week to get the end of the week (per Half-Open definition of a span-of-time).

We could be cute and check to see if both dates are the same. A worthy check if such a case is likely often in your app.

For week 2, let's use a one-liner as alternative syntax.

public boolean inSameWeek ( LocalDate localDate1 , LocalDate localDate2 , DayOfWeek firstDayOfWeek ) {
    Objects.requireNonNull( localDate1 ) ;  // … ditto for other arguments.

    if( localDate1.isEqual( localDate2 ) ) { return true ; }

    TemporalAdjuster ta = TemporalAdjusters.previousOrSame( firstDayOfWeek ) ;

    LocalDate weekStart1 = localDate1.with( ta ) ;
    LocalDate weekStop1 = weekStart1.plusWeeks( 1 ) ;
    LocalDateRange week1 = LocalDateRange.of( weekStart1 , weekStop1 ) ;

    LocalDateRange week2 = 
        LocalDateRange.of(
            localDate2.with( ta ) ,
            localDate2.with( ta ).plusWeeks( 1 ) 
        )
    ;

    // Compare the weeks.
    return week1.equals( week2 ) ;
}

Or even more compact.

public boolean inSameWeek ( LocalDate localDate1 , LocalDate localDate2 , DayOfWeek firstDayOfWeek ) {
    Objects.requireNonNull( localDate1 ) ;  // … ditto for other arguments.

    if( localDate1.isEqual( localDate2 ) ) { return true ; }

    TemporalAdjuster ta = TemporalAdjusters.previousOrSame( firstDayOfWeek ) ;
    return 
        LocalDateRange.of( 
            localDate1.with( ta ) , 
            localDate1.with( ta ).plusWeeks( 1 ) 
        )
        .equals( 
            LocalDateRange.of( 
                localDate2.with( ta ) , 
                localDate2.with( ta ).plusWeeks( 1 ) 
            )
        )
    ;
}

We really do not need that second week. We only care if the first determined week contains the second passed date argument.

public boolean inSameWeek ( LocalDate localDate1 , LocalDate localDate2 , DayOfWeek firstDayOfWeek ) {
    Objects.requireNonNull( localDate1 ) ;  // … ditto for other arguments.

    if( localDate1.isEqual( localDate2 ) ) { return true ; }

    TemporalAdjuster ta = TemporalAdjusters.previousOrSame( firstDayOfWeek ) ;
    return 
        LocalDateRange.of( 
            localDate1.with( ta ) , 
            localDate1.with( ta ).plusWeeks( 1 ) 
        )
        .contains( 
            localDate2
        )
    ;
}

Use it.

LocalDate localDate = LocalDate.of( 2019 , Month.JANUARY , 23 ) ;
LocalDate today = LocalDate.now( ZoneId.of( "Africa/Tunis") ) ;

boolean sameWeek = this.inSameWeek( localDate , today , DayOfWeek.SUNDAY ) ;

Caveat: I ran none of this code.

Upvotes: 0

Sunil Katti
Sunil Katti

Reputation: 33

Although old question - is still relevant. The most upvoted answer here is correct wrt to Joda-time and wrt to JDK8 as well with some syntax changes. Here's one that might help those who are looking around in JDK8 world.

 public static boolean isLocalDateInTheSameWeek(LocalDate date1, LocalDate date2) {
    LocalDate sundayBeforeDate1 = date1.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
    LocalDate saturdayAfterDate1 = date1.with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY));
    return  ((date2.isEqual(sundayBeforeDate1) || date2.isAfter(sundayBeforeDate1)) 
            && (date2.isEqual(saturdayAfterDate1) || date2.isBefore(saturdayAfterDate1)));
}

Upvotes: 2

shanetan
shanetan

Reputation: 11

for those that has to stick to JDK 7 and can't use joda.time, I wrote this method and tested.

public static boolean inSameWeek(Date date1, Date date2) {
    if (null == date1 || null == date2) {
        return false;
    }

    Calendar earlier = Calendar.getInstance();
    Calendar later = Calendar.getInstance();

    if (date1.before(date2)) {
        earlier.setTime(date1);
        later.setTime(date2);
    } else {
        earlier.setTime(date2);
        later.setTime(date1);
    }
    if (inSameYear(date1, date2)) {
        int week1 = earlier.get(Calendar.WEEK_OF_YEAR);
        int week2 = later.get(Calendar.WEEK_OF_YEAR);
        if (week1 == week2) {
            return true;
        }
    } else {
        int dayOfWeek = earlier.get(Calendar.DAY_OF_WEEK); 
        earlier.add(Calendar.DATE, 7 - dayOfWeek);
        if (inSameYear(earlier.getTime(), later.getTime())) {
            int week1 = earlier.get(Calendar.WEEK_OF_YEAR);
            int week2 = later.get(Calendar.WEEK_OF_YEAR);
            if (week1 == week2) {
                return true;
            }
        }
    }
    return false;
}

public static boolean inSameYear(Date date1, Date date2) {
    if (null == date1 || null == date2) {
        return false;
    }
    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(date1);
    int year1 = cal1.get(Calendar.YEAR);
    Calendar cal2 = Calendar.getInstance();
    cal2.setTime(date2);
    int year2 = cal2.get(Calendar.YEAR);
    if (year1 == year2)
        return true;

    return false;
}

Upvotes: 1

Frank
Frank

Reputation: 31086

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.

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1499880

It partly depends on what you mean by "this week" and "next week"... but with Joda Time it's certainly easy to find out whether it's in "today or the next 7 days" as it were:

LocalDate event = getDateFromSomewhere();
LocalDate today = new LocalDate();
LocalDate weekToday = today.plusWeeks(1);
LocalDate fortnightToday = weekToday.plusWeeks(1);

if (today.compareTo(event) <= 0 && event.compareTo(weekToday) < 0)
{
    // It's within the next 7 days
}
else if (weekToday.compareTo(event) <= 0 && event.compareTo(fornightToday) < 0)
{
    // It's next week
}

EDIT: To get the Sunday to Saturday week, you'd probably want:

LocalDate startOfWeek = new LocalDate().withDayOfWeek(DateTimeConstants.SUNDAY);

then do the same code as the above, but relative to startOfWeek.

Upvotes: 8

Jcs
Jcs

Reputation: 13709

You can use the Calendar API to retrieve the week for a given day.

Calendar cal = Calendar.getInstance();
cal.setTime(somedate);
int week = cal.get(Calendar.WEEK_OF_YEAR);

Upvotes: 0

Art Licis
Art Licis

Reputation: 3679

Hint: use Calendar. Create new instance of it for your sample event date. Then, compare WEEK_OF_YEAR for current date, and the date of your event.

Upvotes: 1

Related Questions