180 lines
5.7 KiB
Java
180 lines
5.7 KiB
Java
/**
|
|
*
|
|
*/
|
|
package com.github.javafaker;
|
|
|
|
import java.util.Calendar;
|
|
import java.util.Date;
|
|
import java.util.GregorianCalendar;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
/**
|
|
* A generator of random dates.
|
|
*
|
|
* @author pmiklos
|
|
*
|
|
*/
|
|
public class DateAndTime {
|
|
private static final int DEFAULT_MIN_AGE = 18;
|
|
private static final int DEFAULT_MAX_AGE = 65;
|
|
|
|
private final Faker faker;
|
|
|
|
protected DateAndTime(Faker faker) {
|
|
this.faker = faker;
|
|
}
|
|
|
|
/**
|
|
* Generates a future date from now. Note that there is a 1 second slack to avoid generating a past date.
|
|
*
|
|
* @param atMost
|
|
* at most this amount of time ahead from now exclusive.
|
|
* @param unit
|
|
* the time unit.
|
|
* @return a future date from now.
|
|
*/
|
|
public Date future(int atMost, TimeUnit unit) {
|
|
Date now = new Date();
|
|
Date aBitLaterThanNow = new Date(now.getTime() + 1000);
|
|
return future(atMost, unit, aBitLaterThanNow);
|
|
}
|
|
|
|
/**
|
|
* Generates a future date from now, with a minimum time.
|
|
*
|
|
* @param atMost
|
|
* at most this amount of time ahead from now exclusive.
|
|
* @param minimum
|
|
* the minimum amount of time in the future from now.
|
|
* @param unit
|
|
* the time unit.
|
|
* @return a future date from now.
|
|
*/
|
|
public Date future(int atMost, int minimum, TimeUnit unit) {
|
|
Date now = new Date();
|
|
Date minimumDate = new Date(now.getTime() + unit.toMillis(minimum));
|
|
return future(atMost - minimum, unit, minimumDate);
|
|
}
|
|
|
|
/**
|
|
* Generates a future date relative to the {@code referenceDate}.
|
|
*
|
|
* @param atMost
|
|
* at most this amount of time ahead to the {@code referenceDate} exclusive.
|
|
* @param unit
|
|
* the time unit.
|
|
* @param referenceDate
|
|
* the future date relative to this date.
|
|
* @return a future date relative to {@code referenceDate}.
|
|
*/
|
|
public Date future(int atMost, TimeUnit unit, Date referenceDate) {
|
|
long upperBound = unit.toMillis(atMost);
|
|
|
|
long futureMillis = referenceDate.getTime();
|
|
futureMillis += 1 + faker.random().nextLong(upperBound - 1);
|
|
|
|
return new Date(futureMillis);
|
|
}
|
|
|
|
/**
|
|
* Generates a past date from now. Note that there is a 1 second slack added.
|
|
*
|
|
* @param atMost
|
|
* at most this amount of time earlier from now exclusive.
|
|
* @param unit
|
|
* the time unit.
|
|
* @return a past date from now.
|
|
*/
|
|
public Date past(int atMost, TimeUnit unit) {
|
|
Date now = new Date();
|
|
Date aBitEarlierThanNow = new Date(now.getTime() - 1000);
|
|
return past(atMost, unit, aBitEarlierThanNow);
|
|
}
|
|
|
|
/**
|
|
* Generates a past date from now, with a minimum time.
|
|
*
|
|
* @param atMost
|
|
* at most this amount of time earlier from now exclusive.
|
|
* @param minimum
|
|
* the minimum amount of time in the past from now.
|
|
* @param unit
|
|
* the time unit.
|
|
* @return a past date from now.
|
|
*/
|
|
public Date past(int atMost, int minimum, TimeUnit unit) {
|
|
Date now = new Date();
|
|
Date minimumDate = new Date(now.getTime() - unit.toMillis(minimum));
|
|
return past(atMost - minimum, unit, minimumDate);
|
|
}
|
|
|
|
/**
|
|
* Generates a past date relative to the {@code referenceDate}.
|
|
*
|
|
* @param atMost
|
|
* at most this amount of time past to the {@code referenceDate} exclusive.
|
|
* @param unit
|
|
* the time unit.
|
|
* @param referenceDate
|
|
* the past date relative to this date.
|
|
* @return a past date relative to {@code referenceDate}.
|
|
*/
|
|
public Date past(int atMost, TimeUnit unit, Date referenceDate) {
|
|
long upperBound = unit.toMillis(atMost);
|
|
|
|
long futureMillis = referenceDate.getTime();
|
|
futureMillis -= 1 + faker.random().nextLong(upperBound - 1);
|
|
|
|
return new Date(futureMillis);
|
|
}
|
|
|
|
/**
|
|
* Generates a random date between two dates.
|
|
*
|
|
* @param from
|
|
* the lower bound inclusive
|
|
* @param to
|
|
* the upper bound exclusive
|
|
* @return a random date between {@code from} and {@code to}.
|
|
* @throws IllegalArgumentException
|
|
* if the {@code to} date represents an earlier date than {@code from} date.
|
|
*/
|
|
public Date between(Date from, Date to) throws IllegalArgumentException {
|
|
if (to.before(from)) {
|
|
throw new IllegalArgumentException("Invalid date range, the upper bound date is before the lower bound.");
|
|
}
|
|
|
|
long offsetMillis = faker.random().nextLong(to.getTime() - from.getTime());
|
|
return new Date(from.getTime() + offsetMillis);
|
|
}
|
|
|
|
/**
|
|
* Generates a random birthday between 65 and 18 years ago.
|
|
*
|
|
* @return a random birthday between 65 and 18 years ago.
|
|
*/
|
|
public Date birthday() {
|
|
return birthday(DEFAULT_MIN_AGE, DEFAULT_MAX_AGE);
|
|
}
|
|
|
|
/**
|
|
* Generates a random birthday between two ages.
|
|
*
|
|
* @param minAge
|
|
* the minimal age
|
|
* @param maxAge
|
|
* the maximal age
|
|
* @return a random birthday between {@code minAge} and {@code maxAge} years ago.
|
|
* @throws IllegalArgumentException
|
|
* if the {@code maxAge} is lower than {@code minAge}.
|
|
*/
|
|
public Date birthday(int minAge, int maxAge) {
|
|
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
|
Calendar from = new GregorianCalendar(currentYear - maxAge, 0, 1);
|
|
Calendar to = new GregorianCalendar(currentYear - minAge, 11, 31);
|
|
|
|
return between(from.getTime(), to.getTime());
|
|
}
|
|
|
|
}
|