简体   繁体   中英

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.

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 .

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.

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)));
}

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
}

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;
}

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.

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.

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);

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM