I'm writing some code to populate a MySQL database with random data for testing purposes. I need to populate a DATE
column with random dates from 1970-2015.
Here's the relevant method:
public Date dateGenerator() throws Exception {
Random ry = new Random();
Random rm = new Random();
Random rd = new Random();
int year = 1969 + ry.nextInt(2015-1969+1);
int month = 1 + rm.nextInt(12);
int day = 1 + rm.nextInt(31);
if (month==2 && day>28){
day = day - 3;
} else {
if((month%2==0 && month != 8 ) && day==31 ){
day = day -1;
}
}
}
My purpose is to create three random integers (for day, month, year) and somehow combine them into some Date object to pass to the database. But the database rejects everything I try to feed it.
It would be very educational for me if you can supply me with a suggestion based in the newest java.time
library if this is possible.
A simple way is to convert the minimum and maximum date to their corresponding epoch day, generate a random integer between those two values and finally convert it back to a LocalDate
. The epoch day is obtained with toEpochDay()
which is the count of days since 1970-01-01 (ISO).
The problem with generating a random year, then month and then day is that you have a small chance of falling with an invalid date (like 31st of February). Also, taking a random epoch day guarantees a uniform distribution across all possible dates.
public static void main(String... args) {
long minDay = LocalDate.of(1970, 1, 1).toEpochDay();
long maxDay = LocalDate.of(2015, 12, 31).toEpochDay();
long randomDay = ThreadLocalRandom.current().nextLong(minDay, maxDay);
LocalDate randomDate = LocalDate.ofEpochDay(randomDay);
System.out.println(randomDate);
}
Note that since the minimum date is actually the very first, you could replace it with 0.
To convert this LocalDate
into a java.sql.Date
, you can refer to this post:
java.sql.Date date = java.sql.Date.valueOf(randomDate);
Try something like this.
public static void main(String[] args) {
LocalDate start = LocalDate.of(1970, Month.JANUARY, 1);
long days = ChronoUnit.DAYS.between(start, LocalDate.now());
LocalDate randomDate = start.plusDays(new Random().nextInt((int) days + 1));
System.out.println(randomDate);
}