diff --git a/core/src/main/java/com/tngtech/valueprovider/AbstractValueProvider.java b/core/src/main/java/com/tngtech/valueprovider/AbstractValueProvider.java index c87bf94..1120661 100644 --- a/core/src/main/java/com/tngtech/valueprovider/AbstractValueProvider.java +++ b/core/src/main/java/com/tngtech/valueprovider/AbstractValueProvider.java @@ -10,7 +10,6 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; -import java.time.Month; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; @@ -585,18 +584,57 @@ public LocalDate fixedLocalDate() { } /** - * Draws a {@link LocalDate} in [1st of January of {@code begin} ; 31st of December of {@code end}]. + + * Draws a {@link LocalDate} in [1st of January of {@code startYear} ; 31st of December of {@code endYear}]. + * + * @param startYear the earliest year to draw from. + * @param endYear the latest year to draw from. + * @return the drawn {@link LocalDate}. + * @throws IllegalArgumentException if {@code endYear} < {@code startYear}. + */ + public LocalDate localDateBetweenYears(int startYear, int endYear) { + LocalDate start = LocalDate.ofYearDay(startYear, 1); + LocalDate end = LocalDate.of(endYear, 12, 31); + return localDateBetween(start, end); + } + + /** + * Draws a {@link LocalDate} in [{@code start} ; {@code end}]. + * + * @param start the earliest date to draw from. + * @param end the latest date to draw from. + * @return the drawn {@link LocalDate}. + * @throws IllegalArgumentException if {@code start} > {@code end}. + */ + public LocalDate localDateBetween(LocalDate start, LocalDate end) { + checkArgument(beforeOrEqual(start, end), "start %s must be before or equal end %s", start, end); + return start.plusDays(longNumber(0, DAYS.between(start, end))); + } + + private boolean beforeOrEqual(LocalDate start, LocalDate end) { + return start.isBefore(end) || start.isEqual(end); + } + + /** + * Draws a {@link LocalDate} in [{@code today-pastDuration} ; {@code today}]. * - * @param begin minimum year to draw from. - * @param end maximum year to draw from. + * @param pastDuration the maximum duration in the past to consider drawing from. * @return the drawn {@link LocalDate}. - * @throws IllegalArgumentException if {@code end} < {@code begin}. */ - public LocalDate localDateBetweenYears(int begin, int end) { - checkArgument(begin <= end, "begin %s must be before end %s", begin, end); - LocalDate lower = LocalDate.of(begin, Month.JANUARY, 1); - LocalDate upper = LocalDate.of(end, Month.DECEMBER, 31); - return lower.plusDays(longNumber(0, DAYS.between(lower, upper))); + public LocalDate localDateInPast(Duration pastDuration) { + LocalDate start = fixedLocalDate().minusDays(pastDuration.toDays()); + return localDateBetween(start, fixedLocalDate()); + } + + /** + * Draws a {@link LocalDate} in [{@code today} ; {@code today+futureDuration}]. + * + * @param futureDuration the maximum duration in the future to consider drawing from. + * @return the drawn {@link LocalDate}. + */ + public LocalDate localDateInFuture(Duration futureDuration) { + LocalDate end = fixedLocalDate().plusDays(futureDuration.toDays()); + return localDateBetween(fixedLocalDate(), end); } /** @@ -609,6 +647,58 @@ public LocalTime localTime() { return LocalTime.ofSecondOfDay(longNumber(0, secondsPerDay - 1)); } + /** + * Draws a {@link LocalDateTime} in [{@code start} ; {@code end}]. + * + * @param start the earliest date time to draw from. + * @param end the latest date time to draw from. + * @return the drawn {@link LocalDateTime}. + * @throws IllegalArgumentException if {@code start} > {@code end}. + */ + public LocalDateTime localDateTimeBetween(LocalDateTime start, LocalDateTime end) { + checkArgument(beforeOrEqual(start, end), "start %s must be before or equal end %s", start, end); + return start.plusSeconds(longNumber(0, SECONDS.between(start, end))); + } + + private boolean beforeOrEqual(LocalDateTime start, LocalDateTime end) { + return start.isBefore(end) || start.isEqual(end); + } + + /** + * Draws a {@link LocalDateTime} in [{@code start} T00:00:00 ; {@code end} T23:59:59]. + * + * @param start the earliest date to draw from. + * @param end the latest date to draw from. + * @return the drawn {@link LocalDateTime}. + * @throws IllegalArgumentException if {@code start} > {@code end}. + */ + public LocalDateTime localDateTimeBetween(LocalDate start, LocalDate end) { + return localDateTimeBetween(start.atStartOfDay(), end.atTime(23, 59, 59)); + } + + /** + * Generates a {@link Duration} in [0 ; {@code max}]. + * + * @param max the upper bound of the generated {@link Duration}. + * @return the generated {@link Duration}. + */ + public Duration duration(Duration max) { + return Duration.ofMillis(longNumber(0, max.toMillis())); + } + + /** + * Generates a {@link Duration} in [{@code min} ; {@code max}]. + * + * @param min the lower bound of the generated {@link Duration}. + * @param max the upper bound of the generated {@link Duration}. + * @return the generated {@link Duration}. + * @throws IllegalArgumentException if {@code min} > {@code max}. + */ + public Duration duration(Duration min, Duration max) { + checkArgument(min.compareTo(max) <= 0, "min %s must be less than or equal max %s", min, max); + return Duration.ofMillis(longNumber(min.toMillis(), max.toMillis())); + } + /** * Draws one element from the elements of an Enum class. *
diff --git a/core/src/test/java/com/tngtech/valueprovider/ValueProviderTest.java b/core/src/test/java/com/tngtech/valueprovider/ValueProviderTest.java
index 831c7d7..c352b0a 100644
--- a/core/src/test/java/com/tngtech/valueprovider/ValueProviderTest.java
+++ b/core/src/test/java/com/tngtech/valueprovider/ValueProviderTest.java
@@ -7,7 +7,13 @@
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.Duration;
+import java.time.Duration;
+import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
@@ -21,6 +27,7 @@
import java.util.stream.Stream;
import lombok.Data;
+
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
@@ -94,7 +101,16 @@ private static Collection