All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.rkumsher.date.RandomDateUtils Maven / Gradle / Ivy

The newest version!
package com.github.rkumsher.date;

import static com.github.rkumsher.date.DateUtils.LEAP_DAY;
import static com.github.rkumsher.number.RandomNumberUtils.randomInt;
import static com.github.rkumsher.number.RandomNumberUtils.randomLong;
import static com.github.rkumsher.number.RandomNumberUtils.randomNegativeInt;
import static com.github.rkumsher.number.RandomNumberUtils.randomNegativeLong;
import static com.github.rkumsher.number.RandomNumberUtils.randomPositiveInt;
import static com.github.rkumsher.number.RandomNumberUtils.randomPositiveLong;
import static com.google.common.base.Preconditions.*;
import static java.time.Month.DECEMBER;
import static java.time.Month.JANUARY;
import static java.time.temporal.ChronoField.NANO_OF_DAY;
import static java.time.temporal.ChronoUnit.DAYS;
import static java.time.temporal.ChronoUnit.MILLIS;
import static java.time.temporal.ChronoUnit.MONTHS;

import java.time.Clock;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.MonthDay;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalField;
import java.util.Date;

import org.apache.commons.lang3.RandomUtils;

import com.github.rkumsher.collection.IterableUtils;
import com.github.rkumsher.enums.RandomEnumUtils;

/**
 * Utility library to return random dates, e.g., {@link Instant}s, {@link ZonedDateTime}s, {@link
 * LocalDate}s, {@link Date}s, etc.
 *
 * 

Note: All returned dates will be between 1970 and 9999. */ public final class RandomDateUtils { private static final ZoneId UTC = ZoneId.of("UTC").normalized(); private static final ZoneOffset UTC_OFFSET = ZoneOffset.UTC; private static final int LEAP_YEAR = 2004; private static final int MAX_ZONE_OFFSET_SECONDS = 64800; private static final int MIN_YEAR = 1970; private static final int MAX_YEAR = 9999; /** 1970-01-01T00:00:00Z. */ static final Instant MIN_INSTANT = Instant.ofEpochMilli(0); /** December 31st, 9999. */ static final Instant MAX_INSTANT = Instant.ofEpochMilli( LocalDate.of(MAX_YEAR, 12, 31).atStartOfDay(UTC).toInstant().toEpochMilli()); private RandomDateUtils() {} /** * Returns a random {@link ZonedDateTime} between {@link RandomDateUtils#MIN_INSTANT} and {@link * RandomDateUtils#MAX_INSTANT}. * * @return the random {@link ZonedDateTime} */ public static ZonedDateTime randomZonedDateTime() { return ZonedDateTime.ofInstant(randomInstant(), UTC); } /** * Returns a random {@link ZonedDateTime} within the specified range. * * @param startInclusive the earliest {@link ZonedDateTime} that can be returned * @param endExclusive the upper bound (not included) * @return the random {@link ZonedDateTime} * @throws IllegalArgumentException if startInclusive or endExclusive are null or if endExclusive * is earlier than startInclusive */ public static ZonedDateTime randomZonedDateTime( ZonedDateTime startInclusive, ZonedDateTime endExclusive) { checkArgument(startInclusive != null, "Start must be non-null"); checkArgument(endExclusive != null, "End must be non-null"); Instant instant = randomInstant(startInclusive.toInstant(), endExclusive.toInstant()); return ZonedDateTime.ofInstant(instant, UTC); } /** * Returns a random {@link ZonedDateTime} that is after the current system clock. * * @return the random {@link ZonedDateTime} */ public static ZonedDateTime randomFutureZonedDateTime() { return randomZonedDateTimeAfter(ZonedDateTime.now()); } /** * Returns a random {@link ZonedDateTime} that is after the given {@link ZonedDateTime}. * * @param after the value that returned {@link ZonedDateTime} must be after * @return the random {@link ZonedDateTime} * @throws IllegalArgumentException if after is null or if after is equal to or after {@link * RandomDateUtils#MAX_INSTANT} */ public static ZonedDateTime randomZonedDateTimeAfter(ZonedDateTime after) { checkArgument(after != null, "After must be non-null"); Instant instant = randomInstantAfter(after.toInstant()); return ZonedDateTime.ofInstant(instant, UTC); } /** * Returns a random {@link ZonedDateTime} that is before the current system clock. * * @return the random {@link ZonedDateTime} */ public static ZonedDateTime randomPastZonedDateTime() { return randomZonedDateTimeBefore(ZonedDateTime.now()); } /** * Returns a random {@link ZonedDateTime} that is before the given {@link ZonedDateTime}. * * @param before the value that returned {@link ZonedDateTime} must be before * @return the random {@link ZonedDateTime} * @throws IllegalArgumentException if before is null or if before is equal to or before {@link * RandomDateUtils#MIN_INSTANT} */ public static ZonedDateTime randomZonedDateTimeBefore(ZonedDateTime before) { checkArgument(before != null, "Before must be non-null"); Instant instant = randomInstantBefore(before.toInstant()); return ZonedDateTime.ofInstant(instant, UTC); } /** * Returns a random {@link OffsetDateTime} between {@link RandomDateUtils#MIN_INSTANT} and {@link * RandomDateUtils#MAX_INSTANT}. * * @return the random {@link OffsetDateTime} */ public static OffsetDateTime randomOffsetDateTime() { return OffsetDateTime.ofInstant(randomInstant(), UTC); } /** * Returns a random {@link OffsetDateTime} within the specified range. * * @param startInclusive the earliest {@link OffsetDateTime} that can be returned * @param endExclusive the upper bound (not included) * @return the random {@link OffsetDateTime} * @throws IllegalArgumentException if startInclusive or endExclusive are null or if endExclusive * is earlier than startInclusive */ public static OffsetDateTime randomOffsetDateTime( OffsetDateTime startInclusive, OffsetDateTime endExclusive) { checkArgument(startInclusive != null, "Start must be non-null"); checkArgument(endExclusive != null, "End must be non-null"); Instant instant = randomInstant(startInclusive.toInstant(), endExclusive.toInstant()); return OffsetDateTime.ofInstant(instant, UTC); } /** * Returns a random {@link OffsetDateTime} that is after the current system clock. * * @return the random {@link OffsetDateTime} */ public static OffsetDateTime randomFutureOffsetDateTime() { return randomOffsetDateTimeAfter(OffsetDateTime.now()); } /** * Returns a random {@link OffsetDateTime} that is after the given {@link OffsetDateTime}. * * @param after the value that returned {@link OffsetDateTime} must be after * @return the random {@link OffsetDateTime} * @throws IllegalArgumentException if after is null or if after is equal to or after {@link * RandomDateUtils#MAX_INSTANT} */ public static OffsetDateTime randomOffsetDateTimeAfter(OffsetDateTime after) { checkArgument(after != null, "After must be non-null"); Instant instant = randomInstantAfter(after.toInstant()); return OffsetDateTime.ofInstant(instant, UTC); } /** * Returns a random {@link OffsetDateTime} that is before the current system clock. * * @return the random {@link OffsetDateTime} */ public static OffsetDateTime randomPastOffsetDateTime() { return randomOffsetDateTimeBefore(OffsetDateTime.now()); } /** * Returns a random {@link OffsetDateTime} that is before the given {@link OffsetDateTime}. * * @param before the value that returned {@link OffsetDateTime} must be before * @return the random {@link OffsetDateTime} * @throws IllegalArgumentException if before is null or if before is equal to or before {@link * RandomDateUtils#MIN_INSTANT} */ public static OffsetDateTime randomOffsetDateTimeBefore(OffsetDateTime before) { checkArgument(before != null, "Before must be non-null"); Instant instant = randomInstantBefore(before.toInstant()); return OffsetDateTime.ofInstant(instant, UTC); } /** * Returns a random {@link LocalDateTime} between {@link RandomDateUtils#MIN_INSTANT} and {@link * RandomDateUtils#MAX_INSTANT}. * * @return the random {@link LocalDateTime} */ public static LocalDateTime randomLocalDateTime() { return LocalDateTime.ofInstant(randomInstant(), UTC); } /** * Returns a random {@link LocalDateTime} within the specified range. * * @param startInclusive the earliest {@link LocalDateTime} that can be returned * @param endExclusive the upper bound (not included) * @return the random {@link LocalDateTime} * @throws IllegalArgumentException if startInclusive or endExclusive are null or if endExclusive * is earlier than startInclusive */ public static LocalDateTime randomLocalDateTime( LocalDateTime startInclusive, LocalDateTime endExclusive) { checkArgument(startInclusive != null, "Start must be non-null"); checkArgument(endExclusive != null, "End must be non-null"); Instant startInstant = startInclusive.toInstant(UTC_OFFSET); Instant endInstant = endExclusive.toInstant(UTC_OFFSET); Instant instant = randomInstant(startInstant, endInstant); return LocalDateTime.ofInstant(instant, UTC); } /** * Returns a random {@link LocalDateTime} that is after the current system clock. * * @return the random {@link LocalDateTime} */ public static LocalDateTime randomFutureLocalDateTime() { return randomLocalDateTimeAfter(LocalDateTime.now()); } /** * Returns a random {@link LocalDateTime} that is after the given {@link LocalDateTime}. * * @param after the value that returned {@link LocalDateTime} must be after * @return the random {@link LocalDateTime} * @throws IllegalArgumentException if after is null or if after is equal to or after {@link * RandomDateUtils#MAX_INSTANT} */ public static LocalDateTime randomLocalDateTimeAfter(LocalDateTime after) { checkArgument(after != null, "After must be non-null"); Instant instant = randomInstantAfter(after.toInstant(UTC_OFFSET)); return LocalDateTime.ofInstant(instant, UTC); } /** * Returns a random {@link LocalDateTime} that is before the current system clock. * * @return the random {@link LocalDateTime} */ public static LocalDateTime randomPastLocalDateTime() { return randomLocalDateTimeBefore(LocalDateTime.now()); } /** * Returns a random {@link LocalDateTime} that is before the given {@link LocalDateTime}. * * @param before the value that returned {@link LocalDateTime} must be before * @return the random {@link LocalDateTime} * @throws IllegalArgumentException if before is null or if before is equal to or before {@link * RandomDateUtils#MIN_INSTANT} */ public static LocalDateTime randomLocalDateTimeBefore(LocalDateTime before) { checkArgument(before != null, "Before must be non-null"); Instant instant = randomInstantBefore(before.toInstant(UTC_OFFSET)); return LocalDateTime.ofInstant(instant, UTC); } /** * Returns a random {@link LocalDate} between {@link RandomDateUtils#MIN_INSTANT} and {@link * RandomDateUtils#MAX_INSTANT}. * * @return the random {@link LocalDate} */ public static LocalDate randomLocalDate() { return randomInstant().atZone(UTC).toLocalDate(); } /** * Returns a random {@link LocalDate} within the specified range. * * @param startInclusive the earliest {@link LocalDate} that can be returned * @param endExclusive the upper bound (not included) * @return the random {@link LocalDate} * @throws IllegalArgumentException if startInclusive or endExclusive are null or if endExclusive * is earlier than startInclusive */ public static LocalDate randomLocalDate(LocalDate startInclusive, LocalDate endExclusive) { checkArgument(startInclusive != null, "Start must be non-null"); checkArgument(endExclusive != null, "End must be non-null"); Instant startInstant = startInclusive.atStartOfDay().toInstant(UTC_OFFSET); Instant endInstant = endExclusive.atStartOfDay().toInstant(UTC_OFFSET); Instant instant = randomInstant(startInstant, endInstant); return instant.atZone(UTC).toLocalDate(); } /** * Returns a random {@link LocalDate} that is after the current system clock. * * @return the random {@link LocalDate} */ public static LocalDate randomFutureLocalDate() { return randomLocalDateAfter(LocalDate.now()); } /** * Returns a random {@link LocalDate} that is after the given {@link LocalDate}. * * @param after the value that returned {@link LocalDate} must be after * @return the random {@link LocalDate} * @throws IllegalArgumentException if after is null or if after is equal to or after {@link * RandomDateUtils#MAX_INSTANT} */ public static LocalDate randomLocalDateAfter(LocalDate after) { checkArgument(after != null, "After must be non-null"); Instant instant = randomInstantAfter(after.atStartOfDay(UTC).plus(1, DAYS).toInstant()); return instant.atZone(UTC).toLocalDate(); } /** * Returns a random {@link LocalDate} that is before the current system clock. * * @return the random {@link LocalDate} */ public static LocalDate randomPastLocalDate() { return randomLocalDateBefore(LocalDate.now()); } /** * Returns a random {@link LocalDate} that is before the given {@link LocalDate}. * * @param before the value that returned {@link LocalDate} must be before * @return the random {@link LocalDate} * @throws IllegalArgumentException if before is null or if before is equal to or before {@link * RandomDateUtils#MIN_INSTANT} */ public static LocalDate randomLocalDateBefore(LocalDate before) { checkArgument(before != null, "Before must be non-null"); Instant instant = randomInstantBefore(before.atStartOfDay(UTC).toInstant()); return instant.atZone(UTC).toLocalDate(); } /** * Returns a random {@link Date} between {@link RandomDateUtils#MIN_INSTANT} and {@link * RandomDateUtils#MAX_INSTANT}. * * @return the random {@link Date} */ public static Date randomDate() { return Date.from(randomInstant()); } /** * Returns a random {@link Date} within the specified range. * * @param startInclusive the earliest {@link Date} that can be returned * @param endExclusive the upper bound (not included) * @return the random {@link Date} * @throws IllegalArgumentException if startInclusive or endExclusive are null or if endExclusive * is earlier than startInclusive */ public static Date randomDate(Date startInclusive, Date endExclusive) { checkArgument(startInclusive != null, "Start must be non-null"); checkArgument(endExclusive != null, "End must be non-null"); Instant startInstant = startInclusive.toInstant(); Instant endInstant = endExclusive.toInstant(); Instant instant = randomInstant(startInstant, endInstant); return Date.from(instant); } /** * Returns a random {@link Date} that is after the current system clock. * * @return the random {@link Date} */ public static Date randomFutureDate() { return randomDateAfter(new Date()); } /** * Returns a random {@link Date} that is after the given {@link Date}. * * @param after the value that returned {@link Date} must be after * @return the random {@link Date} * @throws IllegalArgumentException if after is null or if after is equal to or after {@link * RandomDateUtils#MAX_INSTANT} */ public static Date randomDateAfter(Date after) { checkArgument(after != null, "After must be non-null"); Instant instant = randomInstantAfter(after.toInstant()); return Date.from(instant); } /** * Returns a random {@link Date} that is before the current system clock. * * @return the random {@link Date} */ public static Date randomPastDate() { return randomDateBefore(new Date()); } /** * Returns a random {@link Date} that is before the given {@link Date}. * * @param before the value that returned {@link Date} must be before * @return the random {@link Date} * @throws IllegalArgumentException if before is null or if before is equal to or before {@link * RandomDateUtils#MIN_INSTANT} */ public static Date randomDateBefore(Date before) { checkArgument(before != null, "Before must be non-null"); Instant instant = randomInstantBefore(before.toInstant()); return Date.from(instant); } /** * Returns a random {@link Instant} between {@link RandomDateUtils#MIN_INSTANT} and {@link * RandomDateUtils#MAX_INSTANT}. * * @return the random {@link Instant} */ public static Instant randomInstant() { return randomInstant(MIN_INSTANT, MAX_INSTANT); } /** * Returns a random {@link Instant} within the specified range. * * @param startInclusive the earliest {@link Instant} that can be returned * @param endExclusive the upper bound (not included) * @return the random {@link Instant} * @throws IllegalArgumentException if startInclusive or endExclusive are null or if endExclusive * is earlier than startInclusive */ public static Instant randomInstant(Instant startInclusive, Instant endExclusive) { checkArgument(startInclusive != null, "Start must be non-null"); checkArgument(endExclusive != null, "End must be non-null"); checkArgument(!startInclusive.isAfter(endExclusive), "End must be on or after start"); checkArgument( startInclusive.equals(MIN_INSTANT) || startInclusive.isAfter(MIN_INSTANT), "Start must be on or after %s", MIN_INSTANT); checkArgument( endExclusive.equals(MAX_INSTANT) || endExclusive.isBefore(MAX_INSTANT), "End must be on or before %s", MAX_INSTANT); return Instant.ofEpochMilli( RandomUtils.nextLong(startInclusive.toEpochMilli(), endExclusive.toEpochMilli())); } /** * Returns a random {@link Instant} that is after the current system clock. * * @return the random {@link Instant} */ public static Instant randomFutureInstant() { return randomInstantAfter(Instant.now()); } /** * Returns a random {@link Instant} that is after the given {@link Instant}. * * @param after the value that returned {@link Instant} must be after * @return the random {@link Instant} * @throws IllegalArgumentException if after is null or if after is equal to or after {@link * RandomDateUtils#MAX_INSTANT} */ public static Instant randomInstantAfter(Instant after) { checkArgument(after != null, "After must be non-null"); checkArgument(after.isBefore(MAX_INSTANT), "Cannot produce date after %s", MAX_INSTANT); return randomInstant(after.plus(1, MILLIS), MAX_INSTANT); } /** * Returns a random {@link Instant} that is before the current system clock. * * @return the random {@link Instant} */ public static Instant randomPastInstant() { return randomInstantBefore(Instant.now()); } /** * Returns a random {@link Instant} that is before the given {@link Instant}. * * @param before the value that returned {@link Instant} must be before * @return the random {@link Instant} * @throws IllegalArgumentException if before is null or if before is equal to or before {@link * RandomDateUtils#MIN_INSTANT} */ public static Instant randomInstantBefore(Instant before) { checkArgument(before != null, "Before must be non-null"); checkArgument(before.isAfter(MIN_INSTANT), "Cannot produce date before %s", MIN_INSTANT); return randomInstant(MIN_INSTANT, before); } /** * Returns a random {@link LocalTime}. * * @return the random {@link LocalTime} */ public static LocalTime randomLocalTime() { return LocalTime.ofNanoOfDay(random(NANO_OF_DAY)); } /** * Returns a random {@link LocalTime} within the specified range. * * @param startInclusive the earliest {@link LocalTime} that can be returned * @param endExclusive the upper bound (not included) * @return the random {@link LocalTime} * @throws IllegalArgumentException if startInclusive or endExclusive are null or if endExclusive * is earlier than startInclusive */ public static LocalTime randomLocalTime(LocalTime startInclusive, LocalTime endExclusive) { checkArgument(startInclusive != null, "Start must be non-null"); checkArgument(endExclusive != null, "End must be non-null"); long nanoOfDay = random(NANO_OF_DAY, startInclusive.toNanoOfDay(), endExclusive.toNanoOfDay()); return LocalTime.ofNanoOfDay(nanoOfDay); } /** * Returns a random {@link LocalTime} that is after the given {@link LocalTime}. * * @param after the value that the returned {@link LocalTime} must be after * @return the random {@link LocalTime} * @throws IllegalArgumentException if after is null or if after is before {@link LocalTime#MAX} */ public static LocalTime randomLocalTimeAfter(LocalTime after) { checkArgument(after != null, "After must be non-null"); checkArgument(after.isBefore(LocalTime.MAX), "After must be before %s", LocalTime.MAX); long nanoOfDay = randomAfter(NANO_OF_DAY, after.toNanoOfDay() + 1); return LocalTime.ofNanoOfDay(nanoOfDay); } /** * Returns a random {@link LocalTime} that is before the given {@link LocalTime}. * * @param before the value that returned {@link LocalTime} must be before * @return the random {@link LocalTime} * @throws IllegalArgumentException if before is null or if before is after {@link LocalTime#MIN} */ public static LocalTime randomLocalTimeBefore(LocalTime before) { checkArgument(before != null, "Before must be non-null"); checkArgument(before.isAfter(LocalTime.MIN), "Before must be after %s", LocalTime.MIN); long nanoOfDay = randomBefore(NANO_OF_DAY, before.toNanoOfDay()); return LocalTime.ofNanoOfDay(nanoOfDay); } /** * Returns a random valid value for the given {@link TemporalField} between * TemporalField.range().min() and TemporalField.range().max(). For example, * random({@link ChronoField#HOUR_OF_DAY}) will return a random value between 0-23. * *

Note: This will never return {@link Long#MAX_VALUE}. Even if it's a valid value for the * given {@link TemporalField}. * * @param field the {@link TemporalField} to return a valid value for * @return the random value */ public static long random(TemporalField field) { long max = Math.min(field.range().getMaximum(), Long.MAX_VALUE - 1); return randomLong(field.range().getMinimum(), max + 1); } /** * Returns a random valid value for the given {@link TemporalField} between * startInclusive and endExclusive. * * @param field the {@link TemporalField} to return a valid value for * @param startInclusive the smallest value that can be returned * @param endExclusive the upper bound (not included) * @return the random value * @throws IllegalArgumentException if startInclusive is on or before * TemporalField.range().min() * , if endExclusive is on or after TemporalField.range().max(), or if * startInclusive is after after endExclusive */ public static long random(TemporalField field, long startInclusive, long endExclusive) { long min = field.range().getMinimum(); long max = field.range().getMaximum(); checkArgument(startInclusive >= min, "Start must be on or after %s", min); checkArgument(endExclusive <= max, "End must be on or before %s", max); checkArgument(startInclusive <= endExclusive, "End must be on or after start"); min = Math.max(startInclusive, field.range().getMinimum()); max = Math.min(endExclusive, field.range().getMaximum()); return randomLong(min, max); } /** * Returns a random valid value for the given {@link TemporalField} between * after and TemporalField.range().max(). For example, * randomAfter({@link ChronoField#HOUR_OF_DAY}, 12) will return a random value between * 13-23. * *

Note: This will never return {@link Long#MAX_VALUE}. Even if it's a valid value for the * given {@link TemporalField}. * * @param field the {@link TemporalField} to return a valid value for * @param after the value that the returned value must be after * @return the random value * @throws IllegalArgumentException if after is before * TemporalField.range().min() * or if after is on or after TemporalField.range().max() */ public static long randomAfter(TemporalField field, long after) { Long min = field.range().getMinimum(); Long max = field.range().getMaximum(); checkArgument(after < max, "After must be before %s", max); checkArgument(after >= min, "After must be on or after %s", min); return randomLong(after + 1, Math.min(max, Long.MAX_VALUE - 1) + 1); } /** * Returns a random valid value for the given {@link TemporalField} between * TemporalField.range().min() and before. For example, * randomBefore({@link ChronoField#HOUR_OF_DAY}, 13) will return a random value between * 0-12. * * @param field the {@link TemporalField} to return a valid value for * @param before the value that the returned value must be before * @return the random value * @throws IllegalArgumentException if before is after * TemporalField.range().max() * or if before is on or before TemporalField.range().min() */ public static long randomBefore(TemporalField field, long before) { long min = field.range().getMinimum(); long max = field.range().getMaximum(); checkArgument(before > min, "Before must be after %s", min); checkArgument(before <= max, "Before must be on or before %s", max); return randomLong(min, before); } /** * Returns a random {@link MonthDay} between January 1st and December 31st. Includes leap day if * the current year is a leap year. * * @return the random {@link MonthDay} */ public static MonthDay randomMonthDay() { return randomMonthDay(Year.now().isLeap()); } /** * Returns a random {@link MonthDay} between January 1st and December 31st. * * @param includeLeapDay whether or not to include leap day * @return the random {@link MonthDay} */ public static MonthDay randomMonthDay(boolean includeLeapDay) { Month month = randomMonth(); int dayOfMonth = RandomUtils.nextInt(1, month.maxLength() + 1); MonthDay monthDay = MonthDay.of(month, dayOfMonth); if (!includeLeapDay && DateUtils.isLeapDay(monthDay)) { return randomMonthDay(false); } return monthDay; } /** * Returns a random {@link MonthDay} within the specified range. Includes leap day if the current * year is a leap year. * * @param startInclusive the earliest {@link MonthDay} that can be returned * @param endExclusive the upper bound (not included) * @return the random {@link MonthDay} * @throws IllegalArgumentException if startInclusive or endExclusive are null or if endExclusive * is earlier than startInclusive */ public static MonthDay randomMonthDay(MonthDay startInclusive, MonthDay endExclusive) { return randomMonthDay(startInclusive, endExclusive, Year.now().isLeap()); } /** * Returns a random {@link MonthDay} within the specified range. * * @param startInclusive the earliest {@link MonthDay} that can be returned * @param endExclusive the upper bound (not included) * @param includeLeapDay whether or not to include leap day * @return the random {@link MonthDay} * @throws IllegalArgumentException if startInclusive or endExclusive are null, if endExclusive is * earlier than startInclusive, or if startInclusive or endExclusive are leap day and * includeLeapDay is false */ public static MonthDay randomMonthDay( MonthDay startInclusive, MonthDay endExclusive, boolean includeLeapDay) { checkArgument(startInclusive != null, "Start must be non-null"); checkArgument(endExclusive != null, "End must be non-null"); checkArgument( includeLeapDay || !startInclusive.equals(LEAP_DAY) || !endExclusive.equals(LEAP_DAY), "Start and End can't both be leap day"); int year = includeLeapDay ? LEAP_YEAR : LEAP_YEAR - 1; LocalDate start = startInclusive.atYear(year); LocalDate end = endExclusive.atYear(year); LocalDate localDate = randomLocalDate(start, end); return MonthDay.of(localDate.getMonth(), localDate.getDayOfMonth()); } /** * Returns a random {@link MonthDay} that is after the given {@link MonthDay}. Includes leap day * if the current year is a leap year. * * @param after the value that returned {@link MonthDay} must be after * @return the random {@link MonthDay} * @throws IllegalArgumentException if after is null or if after is last day of year (December * 31st) */ public static MonthDay randomMonthDayAfter(MonthDay after) { return randomMonthDayAfter(after, Year.now().isLeap()); } /** * Returns a random {@link MonthDay} that is after the given {@link MonthDay}. * * @param after the value that returned {@link MonthDay} must be after * @param includeLeapDay whether or not to include leap day * @return the random {@link MonthDay} * @throws IllegalArgumentException if after is null or if after is last day of year (December * 31st) */ public static MonthDay randomMonthDayAfter(MonthDay after, boolean includeLeapDay) { checkArgument(after != null, "After must be non-null"); checkArgument(after.isBefore(MonthDay.of(DECEMBER, 31)), "After must be before December 31st"); int year = includeLeapDay ? LEAP_YEAR : LEAP_YEAR - 1; LocalDate start = after.atYear(year).plus(1, DAYS); LocalDate end = Year.of(year + 1).atDay(1); LocalDate localDate = randomLocalDate(start, end); return MonthDay.of(localDate.getMonth(), localDate.getDayOfMonth()); } /** * Returns a random {@link MonthDay} that is before the given {@link MonthDay}. Includes leap day * if the current year is a leap year. * * @param before the value that returned {@link MonthDay} must be before * @return the random {@link MonthDay} * @throws IllegalArgumentException if before is null or if before is first day of year (January * 1st) */ public static MonthDay randomMonthDayBefore(MonthDay before) { return randomMonthDayBefore(before, Year.now().isLeap()); } /** * Returns a random {@link MonthDay} that is before the given {@link MonthDay}. * * @param before the value that returned {@link MonthDay} must be before * @param includeLeapDay whether or not to include leap day * @return the random {@link MonthDay} * @throws IllegalArgumentException if before is null or if before is first day of year (January * 1st) */ public static MonthDay randomMonthDayBefore(MonthDay before, boolean includeLeapDay) { checkArgument(before != null, "Before must be non-null"); checkArgument(before.isAfter(MonthDay.of(JANUARY, 1)), "Before must be after January 1st"); int year = includeLeapDay ? LEAP_YEAR : LEAP_YEAR - 1; LocalDate startOfYear = Year.of(year).atDay(1); LocalDate end = before.atYear(year); LocalDate localDate = randomLocalDate(startOfYear, end); return MonthDay.of(localDate.getMonth(), localDate.getDayOfMonth()); } /** * Returns a random {@link YearMonth} between {@link RandomDateUtils#MIN_INSTANT} and {@link * RandomDateUtils#MAX_INSTANT}. * * @return the random {@link YearMonth} */ public static YearMonth randomYearMonth() { return YearMonth.of(randomYear().getValue(), randomMonth()); } /** * Returns a random {@link YearMonth} within the specified range. * * @param startInclusive the earliest {@link YearMonth} that can be returned * @param endExclusive the upper bound (not included) * @return the random {@link YearMonth} * @throws IllegalArgumentException if startInclusive or endExclusive are null or if endExclusive * is earlier than startInclusive */ public static YearMonth randomYearMonth(YearMonth startInclusive, YearMonth endExclusive) { checkArgument(startInclusive != null, "Start must be non-null"); checkArgument(endExclusive != null, "End must be non-null"); LocalDate start = startInclusive.atDay(1); LocalDate end = endExclusive.atDay(1); LocalDate localDate = randomLocalDate(start, end); return YearMonth.of(localDate.getYear(), localDate.getMonth()); } /** * Returns a random {@link YearMonth} that is after the current system clock. * * @return the random {@link YearMonth} */ public static YearMonth randomFutureYearMonth() { return randomYearMonthAfter(YearMonth.now()); } /** * Returns a random {@link YearMonth} that is after the given {@link YearMonth}. * * @param after the value that returned {@link YearMonth} must be after * @return the random {@link YearMonth} * @throws IllegalArgumentException if after is null or if after is equal to or after {@link * RandomDateUtils#MAX_INSTANT} */ public static YearMonth randomYearMonthAfter(YearMonth after) { checkArgument(after != null, "After must be non-null"); LocalDate start = after.plus(1, MONTHS).atDay(1); LocalDate localDate = randomLocalDateAfter(start); return YearMonth.of(localDate.getYear(), localDate.getMonth()); } /** * Returns a random {@link YearMonth} that is before the current system clock. * * @return the random {@link YearMonth} */ public static YearMonth randomPastYearMonth() { return randomYearMonthBefore(YearMonth.now()); } /** * Returns a random {@link YearMonth} that is before the given {@link YearMonth}. * * @param before the value that returned {@link YearMonth} must be before * @return the random {@link YearMonth} * @throws IllegalArgumentException if before is null or if before is equal to or before {@link * RandomDateUtils#MIN_INSTANT} */ public static YearMonth randomYearMonthBefore(YearMonth before) { checkArgument(before != null, "Before must be non-null"); LocalDate start = before.atDay(1); LocalDate localDate = randomLocalDateBefore(start); return YearMonth.of(localDate.getYear(), localDate.getMonth()); } /** * Returns a random {@link Year} between {@link RandomDateUtils#MIN_INSTANT} and {@link * RandomDateUtils#MAX_INSTANT}. * * @return the random {@link Year} */ public static Year randomYear() { return Year.of(RandomUtils.nextInt(MIN_YEAR, MAX_YEAR)); } /** * Returns a random {@link Year} within the specified range. * * @param startInclusive the earliest {@link Year} that can be returned * @param endExclusive the upper bound (not included) * @return the random {@link Year} * @throws IllegalArgumentException if startInclusive or endExclusive are null, if endExclusive is * earlier than startInclusive, if either are before {@link RandomDateUtils#MIN_INSTANT}, or * if either are after {@link RandomDateUtils#MAX_INSTANT} */ public static Year randomYear(Year startInclusive, Year endExclusive) { checkArgument(startInclusive != null, "Start must be non-null"); checkArgument(endExclusive != null, "End must be non-null"); return randomYear(startInclusive.getValue(), endExclusive.getValue()); } /** * Returns a random {@link Year} within the specified range. * * @param startInclusive the earliest {@link Year} that can be returned * @param endExclusive the upper bound (not included) * @return the random {@link Year} * @throws IllegalArgumentException if endExclusive is earlier than startInclusive, if end is * before {@link RandomDateUtils#MIN_INSTANT}, or if start is after {@link * RandomDateUtils#MAX_INSTANT} */ public static Year randomYear(int startInclusive, int endExclusive) { checkArgument(startInclusive < MAX_YEAR, "Start must be before %s", MAX_YEAR); checkArgument(startInclusive >= MIN_YEAR, "Start must be on or after %s", MIN_YEAR); checkArgument(endExclusive > MIN_YEAR, "End must be after %s", MIN_YEAR); checkArgument(endExclusive <= MAX_YEAR, "End must be on or before %s", MAX_YEAR); checkArgument(startInclusive <= endExclusive, "End must be on or after start"); return Year.of(RandomUtils.nextInt(startInclusive, endExclusive)); } /** * Returns a random {@link Year} that is after the current system clock. * * @return the random {@link Year} */ public static Year randomFutureYear() { return randomYearAfter(Year.now()); } /** * Returns a random {@link Year} that is after the given {@link Year}. * * @param after the value that returned {@link Year} must be after * @return the random {@link Year} * @throws IllegalArgumentException if after is null or if after greater than or equal to {@link * RandomDateUtils#MAX_INSTANT} */ public static Year randomYearAfter(Year after) { checkArgument(after != null, "After must be non-null"); return randomYearAfter(after.getValue()); } /** * Returns a random {@link Year} that is after the given {@link Year}. * * @param after the value that returned {@link Year} must be after * @return the random {@link Year} * @throws IllegalArgumentException if after greater than or equal to {@link * RandomDateUtils#MAX_INSTANT} */ public static Year randomYearAfter(int after) { checkArgument(after < MAX_YEAR, "After must be before %s", MAX_YEAR); return Year.of(RandomUtils.nextInt(after + 1, MAX_YEAR)); } /** * Returns a random {@link Year} that is before the current system clock. * * @return the random {@link Year} */ public static Year randomPastYear() { return randomYearBefore(Year.now()); } /** * Returns a random {@link Year} that is before the given {@link Year}. * * @param before the value that returned {@link Year} must be before * @return the random {@link Year} * @throws IllegalArgumentException if before is null or if before is less than or equal to {@link * RandomDateUtils#MIN_INSTANT} */ public static Year randomYearBefore(Year before) { checkArgument(before != null, "Before must be non-null"); return randomYearBefore(before.getValue()); } /** * Returns a random {@link Year} that is before the given {@link RandomDateUtils#MIN_INSTANT}. * * @param before the value that returned {@link Year} must be before * @return the random {@link Year} * @throws IllegalArgumentException if before is less than or equal to 1970 */ public static Year randomYearBefore(int before) { checkArgument(before > MIN_YEAR, "Before must be after %s", MIN_YEAR); return Year.of(RandomUtils.nextInt(MIN_YEAR, before)); } /** * Returns a random {@link Clock} in the UTC {@link ZoneId} with a random instant in time. * * @return the random {@link Clock} */ public static Clock randomFixedUtcClock() { return Clock.fixed(randomInstant(), UTC); } /** * Returns a random {@link Clock} in a random {@link ZoneId} with a random instant in time. * * @return the random {@link Clock} */ public static Clock randomFixedClock() { return Clock.fixed(randomInstant(), randomZoneId()); } /** * Returns a random {@link ZoneId} from {@link ZoneOffset#getAvailableZoneIds()}. * * @return the random {@link ZoneId} */ public static ZoneId randomZoneId() { return ZoneId.of(IterableUtils.randomFrom(ZoneOffset.getAvailableZoneIds())); } /** * Returns a random {@link DayOfWeek}. * * @return the random {@link DayOfWeek} */ public static DayOfWeek randomDayOfWeek() { return RandomEnumUtils.random(DayOfWeek.class); } /** * Returns a random {@link Month}. * * @return the random {@link Month} */ public static Month randomMonth() { return RandomEnumUtils.random(Month.class); } /** * Returns a random {@link ZoneOffset} (-18:00 to +18:00). * * @return the random {@link ZoneOffset} */ public static ZoneOffset randomZoneOffset() { int totalSeconds = MAX_ZONE_OFFSET_SECONDS - RandomUtils.nextInt(0, MAX_ZONE_OFFSET_SECONDS * 2 + 1); return ZoneOffset.ofTotalSeconds(totalSeconds); } /** * Returns a random {@link Period} which may be positive, negative, or {@link Period#ZERO}. * * @return the random {@link Period} */ public static Period randomPeriod() { return Period.of(randomInt(), randomInt(), randomInt()); } /** * Returns a random {@link Period} which will be positive. * * @return the random {@link Period} */ public static Period randomPositivePeriod() { return Period.of(randomPositiveInt(), randomPositiveInt(), randomPositiveInt()); } /** * Returns a random {@link Period} which will be negative. * * @return the random {@link Period} */ public static Period randomNegativePeriod() { return Period.of(randomNegativeInt(), randomInt(), randomInt()); } /** * Returns a random {@link Duration} which may be positive, negative, or {@link Duration#ZERO}. * * @return the random {@link Duration} */ public static Duration randomDuration() { return Duration.ofNanos(randomLong()); } /** * Returns a random {@link Duration} which will be positive. * * @return the random {@link Duration} */ public static Duration randomPositiveDuration() { return Duration.ofNanos(randomPositiveLong()); } /** * Returns a random {@link Duration} which will be negative. * * @return the random {@link Duration} */ public static Duration randomNegativeDuration() { return Duration.ofNanos(randomNegativeLong()); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy