Is there a java class that represent a range between two instants?
Asked Answered
H

5

5

I do want to check if an Instant is between two other instants:

Currently I use:

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

Is there any other utility function is the standard library or elsewhere that allows for this kind of range check is a simplified way?

I'm looking for something like:

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

// or

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

Halation answered 6/11, 2019 at 12:18 Comment(2)
I don't think there is. This seems to me both too trivial to do, and too depending on the use-cases every different programmers will identifies, to be a great candidate for providing it along with the language.Honna
Also, note that "is equals or is after" is equivalent to "is not before"Honna
R
2

Not natively. See https://mcmap.net/q/179629/-how-do-i-check-if-a-date-is-within-a-certain-range which gives the "inclusive" example of:

containsNow = !now.isBefore( start ) && now.isBefore( stop );
Rodneyrodolfo answered 6/11, 2019 at 12:41 Comment(0)
D
6

You can use Interval in ThreeTen-Extra for a task like this. (Assuming you are willing o pull in a library)

Doubles answered 6/11, 2019 at 12:34 Comment(0)
B
3

My lib Time4J offers MomentInterval which is interoperable with the type Instant and also allows either half-open (default) or closed intervals. Example:

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

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

Testing if an interval contains a test instant is easy, for example:

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

I agree that using an extra lib is probably overkill if you only want to do this simple in-range-test, but if you like to manipulate intervals or to do complex queries in interval trees then my lib might be interesting enough for you, see the other classes in the range-package.

Bubaline answered 6/11, 2019 at 12:56 Comment(3)
I briefly looked at the library in the github. Seems very impressiveRoter
@MichaelGantman Thanks, by the way, I could also have mentioned the class SimpleInterval<Instant> because it always operates directly with Instant, however, it does not allow closed intervals what the OP wants, too (IMHO a little bit strange request for instants which have a time portion).Bubaline
not the right forum for this, but I couldn't find your contact info. Please look me up on LinkedIn and connect, please. On my page I have some Date formatting related articles and an article about my own Open source lib. I would like to hear your opinion. After (and if) you connect I would delee this comment as it is not related to this questionRoter
R
2

Not natively. See https://mcmap.net/q/179629/-how-do-i-check-if-a-date-is-within-a-certain-range which gives the "inclusive" example of:

containsNow = !now.isBefore( start ) && now.isBefore( stop );
Rodneyrodolfo answered 6/11, 2019 at 12:41 Comment(0)
H
2

I realized thanks to @kumesana comment that the the range check can be simplified into a more readable form by taking advantage that testSubject2.equals(start) || testSubject2.isAfter(start) can be effectively replaced with !testSubject2.isBefore(start) so the inclusive range check can be implemented as:

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

Alternatively, I found that the Joda Time library has org.joda.time.Interval that allows for range checks via .contains() but that requires converting my java.time.Instants to org.joda.time.Instant, so the ThreeTen-Extra library from the other answer seems more appropriate since it works with regular java.time.Instant.

Halation answered 6/11, 2019 at 12:55 Comment(1)
That "other answer" is by the author of Joda Time, ThreeTen-Extra, and the java.time library, Stephen Colbourne, so it's about as authoritative an answer as it is possible to get!Soapy
R
1

In JDK 8, no there is no such class. There are 2 classes that may provide partial support for your needs. It is Period and Duration

Roter answered 6/11, 2019 at 12:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.