Skip to content

Commit

Permalink
docs: Improving docs on Interval.timesBetween
Browse files Browse the repository at this point in the history
  • Loading branch information
politeRaccoon committed Jul 3, 2024
1 parent a05d62c commit 1683c05
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 4 deletions.
17 changes: 15 additions & 2 deletions src/main/java/org/mitre/caasd/commons/Interval.java
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,21 @@ public static Stream<Instant> datesBetween(Instant start, Instant end) {
}

/**
* Returns a stream of the epoch floors at the given width between the two dates. I.e. returns
* time bins of size width between start and end.
* Returns a stream of "rounded times" occurring btw the two Instants.
*
* @param start An instant that usually occurs BEFORE the first Instant in the stream. When
* start is a perfect multiple of the width Duration then start will be the first
* value in the output steam (e.g., if the duration width = 5 minutes and start =
* 12:05:00.000 then the start Instant will appear in the output stream)
* @param end An instant that always occurs AFTER the last Instant in the stream.
*
* @return A stream of "Rounded Instants" that come between the start and end. For example, if
* start = 13:52:45 and end = 15:14:45 (82 min apart) timesBetween(start, end,
* Duration.ofMinutes(15)) will return a Stream containing: {14:00:00, 14:15:00, 14:30:00,
* 14:45:00, and 15:00:00}
* <p>
* Returns a stream of the epoch floors at the given width between the two dates. I.e.
* returns time bins of size width between start and end.
*/
public static Stream<Instant> timesBetween(Instant start, Instant end, Duration width) {
if ((end.toEpochMilli() - start.toEpochMilli()) / width.toMillis() > 99999) {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/mitre/caasd/commons/Pair.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@
* Similarly, it is also a mistake to serialize an {@literal ArrayList<T>} when T is
* non-serializable. Despite this vulnerability it is useful for ArrayList, and Pair, to be
* Serializable.
* <p>
* This class is Deprecated to encourage usage of Java Record classes. This class may or may not be
* removed in the future.
*/
@Deprecated
public class Pair<L, R> implements Serializable {

private static final long serialVersionUID = 1L;
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/mitre/caasd/commons/Triple.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@
* Similarly, it is also a mistake to serialize an {@literal ArrayList<T>} when T is
* non-serializable. Despite this vulnerability it is useful for ArrayList, and Triple, to be
* Serializable.
* <p>
* This class is Deprecated to encourage usage of Java Record classes. This class may or may not be
* removed in the future.
*/
@Deprecated
public class Triple<A, B, C> implements Serializable {

private static final long serialVersionUID = 1L;
Expand Down
46 changes: 44 additions & 2 deletions src/test/java/org/mitre/caasd/commons/IntervalTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
import static java.time.Instant.EPOCH;
import static java.time.temporal.ChronoUnit.DAYS;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.*;
import static org.mitre.caasd.commons.Interval.timesBetween;

import java.time.Duration;
import java.time.Instant;
Expand Down Expand Up @@ -113,12 +115,52 @@ public void testIntervalTimesBetween() {
.mapToObj(l -> EPOCH.plus(Duration.ofHours(12 * l + 24)))
.collect(Collectors.toSet());

Set<Instant> itvTimes = Interval.timesBetween(itv.start(), itv.end(), Duration.ofHours(12))
.collect(Collectors.toSet());
Set<Instant> itvTimes =
timesBetween(itv.start(), itv.end(), Duration.ofHours(12)).collect(Collectors.toSet());

assertEquals(Sets.intersection(times, itvTimes).size(), times.size());
}

@Test
public void timeBetween_instantsAreRounded_doNotCoverEntireInterval() {

Instant start = Instant.parse("2024-07-03T13:52:45.057Z");
Instant end = Instant.parse("2024-07-03T15:14:45.057Z"); // 82 minutes later..

Instant[] times = timesBetween(start, end, Duration.ofMinutes(15)).toArray(Instant[]::new);

assertThat(times.length, is(5));
assertThat(times[0], is(Instant.parse("2024-07-03T14:00:00Z")));
assertThat(times[1], is(Instant.parse("2024-07-03T14:15:00Z")));
assertThat(times[2], is(Instant.parse("2024-07-03T14:30:00Z")));
assertThat(times[3], is(Instant.parse("2024-07-03T14:45:00Z")));
assertThat(times[4], is(Instant.parse("2024-07-03T15:00:00Z")));

assertThat(start.isBefore(times[0]), is(true));
assertThat(end.isAfter(times[4]), is(true));

Duration inputDuration = Duration.between(start, end); // 82 min
Duration outputDuration = Time.durationBtw(times); // 60 min

assertThat(inputDuration.toMillis(), greaterThan(outputDuration.toMillis()));
}

@Test
public void timeBetween_startAndEnd() {

Instant start = Instant.parse("2024-07-03T14:00:00Z");
Instant end = Instant.parse("2024-07-03T15:00:00Z"); // 60 minutes later..

Instant[] times = timesBetween(start, end, Duration.ofMinutes(15)).toArray(Instant[]::new);

assertThat(times.length, is(4));

assertThat(times[0], is(Instant.parse("2024-07-03T14:00:00Z")));
assertThat(times[1], is(Instant.parse("2024-07-03T14:15:00Z")));
assertThat(times[2], is(Instant.parse("2024-07-03T14:30:00Z")));
assertThat(times[3], is(Instant.parse("2024-07-03T14:45:00Z")));
}

@Test
public void testComplementOf() {
Interval base = new Interval(EPOCH.plusMillis(0L), EPOCH.plusMillis(10L));
Expand Down

0 comments on commit 1683c05

Please sign in to comment.