Как определить, находится ли дата в этой или следующей неделе в Java? - PullRequest
6 голосов
/ 27 декабря 2010

Если у меня есть дата события, например 2011-01-03, как определить, будет ли это в течение этой или следующей недели в Java? Любой пример кода?

Редактировать:

Я думал, что это был простой вопрос, он оказался более сложным, чем я думал, что я рассматриваю на этой неделе: от этого прошлого Солнца до этого Суб, следующая неделя от следующего Солнца до Сат после этого.

Ответы [ 8 ]

7 голосов
/ 27 декабря 2010

Отчасти это зависит от того, что вы подразумеваете под «этой неделей» и «следующей неделей» ... но с Joda Time , конечно, легко определить, в «сегодня» или в следующие 7 дней как бы:

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
}

РЕДАКТИРОВАТЬ: Чтобы получить неделю с воскресенья по субботу, вы, вероятно, хотели бы:

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

затем выполните тот же код, что и выше, но относительно startOfWeek.

2 голосов
/ 21 мая 2019

Хотя старый вопрос - все еще актуален.Наиболее одобренный ответ здесь правильный по Joda-time и по JDK8, а также с некоторыми изменениями синтаксиса.Вот тот, который может помочь тем, кто смотрит в мир JDK8.

 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)));
}
2 голосов
/ 27 декабря 2010

Как насчет этого:

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

Результат:

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

Любой день между первыми двумя - это эта неделя, любые промежутки между последними двумя - следующая неделя.

1 голос
/ 26 мая 2019

Большинство ответов здесь не удовлетворяют меня.Они либо используют устаревший Calendar -API (извините в старых ответах, данных до Java 8, и поэтому неправильно критиковать такие ответы), либо даже частично ошибочны или излишне сложны.Например, наиболее одобренный ответ Джона Скита предлагает определить первый день недели по выражению Йода new LocalDate().withDayOfWeek(DateTimeConstants.SUNDAY).Но в таком коде используется определение ISO недели, начинающейся в понедельник, в результате чего, если текущая дата не в воскресенье, код будет генерироваться в следующее воскресенье, а не в предыдущее воскресенье, как того требует OP.Joda-Time не в состоянии обрабатывать недели, не относящиеся к ISO.

Еще один незначительный недостаток других ответов - не заботиться о том, содержит ли текущая И СЛЕДУЮЩАЯ неделя заданную дату - по запросу ОП.1006 * Итак, вот мое улучшенное предложение в современной 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));

Примечание: вопрос вдохновил меня на добавление небольшого улучшения в класс DateInterval в моей библиотеке Time4J как определить текущую календарную неделю очень общим способом.

1 голос
/ 10 декабря 2015

для тех, кто придерживается JDK 7 и не может использовать joda.time, я написал этот метод и протестировал.

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;
}
1 голос
/ 27 декабря 2010

Подсказка: используйте Календарь. Создайте новый экземпляр для вашей даты события. Затем сравните WEEK_OF_YEAR для текущей даты и даты вашего события.

0 голосов
/ 22 мая 2019

ТЛ; др

Тестирование пары LocalDate объектов с использованием класса org.threeten.extra.LocalDateRange с TemporalAdjuster с именем ta, который определяет первый день недели.

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

ThreeTen-Extra

Проект ThreeTen-Extra добавляет дополнительные функциональные возможности к классам java.time , встроенным в Java (определяется JSR 310).

Среди добавленных классов - LocalDateRange. Этот класс представляет промежуток времени, привязанный к временной шкале. Другими словами, пара LocalDate объектов. Этот класс предлагает удобные методы для сравнения, такие как overlaps, contains и abuts. Здесь нам нужно equals.

Определите метод, в котором вы передаете две даты плюс первый день недели (объект перечисления DayOfWeek).

Мы используем TemporalAdjuster, найденный в классе TemporalAdjusters, чтобы определить дату первого дня недели. Затем добавьте неделю, чтобы получить конец недели (для определения полуоткрытого промежутка времени).

Мы могли бы быть милыми и проверить, совпадают ли обе даты. Достойная проверка, если такой случай часто встречается в вашем приложении.

Для недели 2, давайте использовать однострочник в качестве альтернативного синтаксиса.

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

Или даже более компактный.

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

Нам действительно не нужна эта вторая неделя. Нам важно только, если первая определенная неделя содержит второй аргумент прошедшей даты.

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

Используйте это.

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

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

Предупреждение: я не запускал ни один из этих кодов.

0 голосов
/ 27 декабря 2010

Вы можете использовать API Календаря, чтобы получить неделю для данного дня.

Calendar cal = Calendar.getInstance();
cal.setTime(somedate);
int week = cal.get(Calendar.WEEK_OF_YEAR);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...