Есть ли класс Java, представляющий диапазон между двумя моментами? - PullRequest
1 голос
/ 06 ноября 2019

Я хочу проверить, находится ли мгновение между двумя другими моментами:

В настоящее время я использую:

import java.time.format.DateTimeFormatter;
import java.time.Instant;

Instant start = Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse("2016-10-25T12:31:39.084726218Z"));
Instant end = Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse("2016-10-25T13:31:39.084726218Z"));


// for exclusive range 
Instant testSubject1 = Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse("2016-10-25T12:31:40Z"));
boolean isInRange1 = testSubject1.isAfter(start) && testSubject1.isBefore(end); // this works as exclusive range

//for inclusive range
Instant testSubject2 = Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse("2016-10-25T12:31:39.084726218Z"));
boolean isInRange2 = (testSubject2.equals(start) || testSubject2.isAfter(start)) && (testSubject2.equals(end) || testSubject2.isBefore(end)); // inclusive range

Есть ли какая-либо другая служебная функция в стандартной библиотеке или в другом месте, которая позволяетдля этого вида проверки диапазона это упрощенный способ?

Я ищу что-то вроде:

new InstantRange(start,end).checkInstantWithin(testSubject1); 

// or

InstantUtils.inRangeExclusive(start,end, testSubject1);
InstantUtils.inRangeInclusivestart,end, testSubject1);

Ответы [ 5 ]

5 голосов
/ 06 ноября 2019

Вы можете использовать Interval в ThreeTen-Extra для подобных задач. (Предполагая, что вы готовы взять библиотеку)

3 голосов
/ 06 ноября 2019

My lib Time4J предлагает MomentInterval , который совместим с типом Instant, а также допускает полуоткрытые (по умолчанию) или закрытые интервалы. Пример:

Instant start = ...;
Instant end = ...;

MomentInterval interval = MomentInterval.between(start, end); // half-open (end exclusive)
MomentInterval closed = interval.withClosedEnd(); // (inclusive)

Тестирование, если интервал содержит тестовый момент, легко, например:

boolean isInRange = interval.contains(Moment.from(testInstant));

Я согласен, что использование дополнительной библиотеки, вероятно, излишне, если вы только хотите сделатьэто простой тест in-range, но если вам нравится манипулировать интервалами или выполнять сложные запросы в деревьях интервалов, моя библиотека может быть вам достаточно интересна, посмотрите другие классы в range-package .

2 голосов
/ 06 ноября 2019

Благодаря комментарию @kumesana я понял, что проверку диапазона можно упростить до более читаемой формы, воспользовавшись тем, что testSubject2.equals(start) || testSubject2.isAfter(start) может быть эффективно заменен на !testSubject2.isBefore(start), поэтому проверка включаемого диапазона может быть реализована следующим образом:

private boolean timestampInRange(Instant start, Instant end, Instant subject) {
   return !subject.isBefore(start) && !subject.isAfter(end);
}

Кроме того, я обнаружил, что в библиотеке Joda Time есть org.joda.time.Interval, которая позволяет выполнять проверку диапазона через .contains(), но для этого требуется преобразовать мой java.time.Instants вorg.joda.time.Instant, поэтому библиотека ThreeTen-Extra из другого ответа представляется более подходящей, поскольку она работает с обычным java.time.Instant.

1 голос
/ 06 ноября 2019

В JDK 8 нет такого класса. Есть 2 класса, которые могут предоставить частичную поддержку для ваших нужд. Это Период и Продолжительность

1 голос
/ 06 ноября 2019

Не изначально. См. https://stackoverflow.com/a/35300229/628318, который дает «включающий» пример:

containsNow = !now.isBefore( start ) && now.isBefore( stop );
...