Вопрос по java, time – Как проверить, что период времени перекрывает другой период времени в Java

9

Как проверить, что период времени перекрывает другой период в том же дне.

Например,

С 7:00 до 10:30 перекрывается с 10:00 до 11:30С 7:00 до 10:30 перекрывается с 8:00 до 9:00С 7:00 до 10:30 перекрывается с 5:00 до 8:00
Я не храню свой период времени. Я хочу найти перекрывающееся время. например (с 7:00 до 10:30 утра перекрывается с 10:00 до 11:30 утра) это время перекрывается. Таким образом, я получил пятьдесят пар времени. поэтому я хочу проверить, что каждая пара с другой парой. Gary
Когда я сказал "Как ты'сохраняя егоЯ имел ввиду какой тип данных? Это влияет на возможные ответы (как Visionary упоминает в своем ответе, эта функциональность предоставляется, если выповторное использование времени Joda). Насколько мы знаем, периоды могут быть текстовыми строками "С 7:00 до 10:30, который бы нуждался в разборе. Или время может быть сохранено как дата Java. Или значения с плавающей запятой с 0.0, равным эпохе 1970-01-01 00:00. icabod
Нам нужно больше деталей - это зависит от того, как высохраняя ваш период времени. Этоjava.time.Period? В общем, чтобы проверить, не перекрываются ли два периода времени, сравните время начала и окончания каждого из них. icabod

Ваш Ответ

5   ответов
1

какой-то процесс еще не завершен) и дата окончания может быть нулевой:

public static boolean isOverlapping(Date start1, Date end1, Date start2, Date end2)
{
    return
            ((null == end2) || start1.before(end2)) &&
            ((null == end1) || start2.before(end1)) ;
}
1

Вот метод работы:

public boolean isOverlapping(Date von1, Date bis1, Date von2, Date bis2) {
    return von1.compareTo(bis2) <= 0 && bis1.compareTo(von2) >= 0;
}

И вот доказательство для всех, чтобы попробовать это:

@Test
public void isOverlapping_base() {
    Assert.assertTrue(isOverlapping(getDate(2014, 1, 1),
            getDate(2014, 3, 31), getDate(2014, 1, 2),
            getDate(2014, 4, 1)));

    Assert.assertTrue(isOverlapping(getDate(2014, 1, 2),
            getDate(2014, 4, 1), getDate(2014, 1, 1),
            getDate(2014, 3, 31)));

    Assert.assertTrue(isOverlapping(getDate(2014, 1, 1),
            getDate(2014, 4, 1), getDate(2014, 1, 2),
            getDate(2014, 3, 31)));

    Assert.assertTrue(isOverlapping(getDate(2014, 1, 2),
            getDate(2014, 3, 31), getDate(2014, 1, 1),
            getDate(2014, 4, 1)));

    Assert.assertFalse(isOverlapping(getDate(2014, 1, 1),
            getDate(2014, 1, 31), getDate(2014, 3, 1),
            getDate(2014, 3, 31)));

    Assert.assertFalse(isOverlapping(getDate(2014, 3, 1),
            getDate(2014, 3, 31), getDate(2014, 1, 1),
            getDate(2014, 1, 31)));
}

Date getDate(int year, int month, int date) {
    Calendar working = Calendar.getInstance();
    working.set(year, month - 1, date, 0, 0, 0); 
    working.set(Calendar.MILLISECOND, 0);
    return working.getTime();
}
26

public static boolean isOverlapping(Date start1, Date end1, Date start2, Date end2) {
    return start1.before(end2) && start2.before(end1);
}

Этот код требует, чтобы между двумя периодами было как минимум одна миллисекунда для совместного использования.true

Если примыкающие периоды времени считаютсяперекрытие» (например, 10: 00-10: 30 и 10: 30-11: 00) логику нужно немного подправить:

public static boolean isOverlapping(Date start1, Date end1, Date start2, Date end2) {
    return !start1.after(end2) && !start2.after(end1);
}

Эта логика чаще встречается в запросах к базе данных, но тот же подход применяется в любом контексте.

Как только вы понимаете, насколько это просто, вы сначала пинаете себя, а потом кладете в банк!

@JoopEggen Мне было интересно, сколько времени понадобится кому-то, чтобы заметить об этом. Хотя ни один из примеров не охватывает этот крайний случай, я отредактировал свой ответ, чтобы представить альтернативное, но не менее изящное (приятнее, чем ваше :)) решение, которое обслуживает периоды слияния, если их следует рассматривать как перекрывающиеся. Bohemian
ага, логический эксперт; извинения за мой== false затем ;). Тем не менее, первое решение кажется наиболее подходящим. Joop Eggen
before (а такжеafter) значит строго раньше. Следовательно, период не нулевой длины:.start1.before(start1) == false Joop Eggen
4

функциональность запеченная в, Это'очень хорошо построен и на маршруте JSR, чтобы заменить сломанный Java Calendar API. Вы, вероятно, должны рассмотреть возможность его использования.

3
ТЛ; др
( startA.isBefore( stopB ) ) && ( stopA.isAfter( startB ) ) 
LocalTime

кста даты и часового пояса, используйтеLocalTime учебный класс.

LocalTime startA = LocalTime.of( 7 , 0 );
LocalTime stopA = LocalTime.of( 10 , 30 );

LocalTime startB = LocalTime.of( 10 , 0 );
LocalTime stop2B = LocalTime.of( 11 , 30 );

Проверьте данные, убедившись, что окончание идет после начала (или равно). Более короткий способ сказать, что это «начало не после окончания ».

Boolean validA = ( ! startA.isAfter( stopA ) ) ;
Boolean validB = ( ! startB.isAfter( stop2B ) ) ;

вэтот ответ отМено Хохшильд, используя подход Half-Open для определения промежутка времени, когда началовключительно в то время как окончаниеэксклюзивныймы можем использовать эту логику:

(StartA < EndB) и (EndA> StartB)

Boolean overlaps = ( 
    ( startA.isBefore( stopB ) ) 
    && 
    ( stopA.isAfter( startB ) ) 
) ;

Обратите внимание, чтоLocalTime ограничен одним общим 24-часовым днем. Время не может идти за полночь, не может переходить в другое. Естьнет другие дни, чтобы рассмотреть.

ZonedDateTime

Если вы хотите проверить фактические моменты на временной шкале, вы должны настроить эти объекты времени дня в контексте дат и часового пояса. ПрименитьZoneId чтобы получитьZonedDateTime объект.

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
ZonedDateTime zdt = ZonedDateTime.of( today , startA , z);
О java.time

java.time фреймворк встроен в Java 8 и выше. Эти классы вытесняют хлопотное староенаследие классы даты и времени, такие как, &java.util.DateCalendar ,SimpleDateFormat

Joda времени проект, сейчас вРежим технического обслуживанияПосоветует миграцию наjava.time классы.

Чтобы узнать больше, см.Oracle Tutorial, И поиск переполнения стека для многих примеров и объяснений. СпецификацияJSR 310.

Где взять классы java.time?

Java SE 8,Java SE 9, и позжеВстроенный.Часть стандартного Java API с комплексной реализацией.Java 9 добавляет некоторые незначительные функции и исправления.Java SE 6 а такжеJava SE 7Большая часть функциональности java.time перенесена на Java 6 & 7 вThreeTen-Backport.AndroidThreeTenABP проект адаптируетсяThreeTen-Backport (упомянуто выше) специально для Android.УвидетьКак использовать ThreeTenABP ....

ThreeTen-Extra Проект расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь, такие как,IntervalYearWeekYearQuarter, а такжеБольше.

Похожие вопросы