4

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

RubenLaguna
  • 21,435
  • 13
  • 113
  • 151
  • 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. – kumesana Nov 06 '19 at 12:31
  • 1
    Also, note that "is equals or is after" is equivalent to "is not before" – kumesana Nov 06 '19 at 12:32

5 Answers5

6

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

JodaStephen
  • 60,927
  • 15
  • 95
  • 117
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.

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
  • I briefly looked at the library in the github. Seems very impressive – Michael Gantman Nov 06 '19 at 14:31
  • @MichaelGantman Thanks, by the way, I could also have mentioned the class `SimpleInterval` 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). – Meno Hochschild Nov 06 '19 at 16:03
  • 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 question – Michael Gantman Nov 06 '19 at 16:34
2

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

containsNow = !now.isBefore( start ) && now.isBefore( stop );
drekbour
  • 2,895
  • 18
  • 28
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.

RubenLaguna
  • 21,435
  • 13
  • 113
  • 151
  • 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! – Matthew Leidholm Nov 06 '19 at 21:42
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

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36