RubenLaguna
RubenLaguna

Reputation: 24686

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

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

Upvotes: 5

Views: 4030

Answers (5)

Meno Hochschild
Meno Hochschild

Reputation: 44061

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.

Upvotes: 3

RubenLaguna
RubenLaguna

Reputation: 24686

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.

Upvotes: 2

Michael Gantman
Michael Gantman

Reputation: 7790

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

Upvotes: 1

drekbour
drekbour

Reputation: 3081

Not natively. See https://stackoverflow.com/a/35300229/628318 which gives the "inclusive" example of:

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

Upvotes: 2

JodaStephen
JodaStephen

Reputation: 63385

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

Upvotes: 6

Related Questions