这是我参与新手入门的第1篇文章。
前言
Java 本身提供了随机数字的生成方法,也提供了很多日期函数,用来操作日期、时间。
下面我们看一下如何结合二者,在 Java 中生成随机日期。
知识点
我们一般认为日期/时间是类似下面的字符串:
- 2021-07-05 12:30:45
- 2021年7月5日
- 12:30:45
实际上,对于计算机而言,日期和时间只不过是 32 位整数,因此我们可以按照以下简单算法生成随机时间值:
- 生成一个随机的 32 位数字,即一个int值
- 将生成的随机值传递给适当的日期和时间构造函数
利用 Date
在 jdk 中,java.util.Date
是最常用的时间类之一。它的构造器可以接受一个毫秒值来初始化一个时间点。
public static Date between(Date start, Date end) {
long startMillis = start.getTime();
long endMillis = end.getTime();
long randomMillis = ThreadLocalRandom
.current()
.nextLong(startMillis, endMillis);
return new Date(randomMillis);
}
复制代码
只需要传入开始时间和结束时间,上述方法可以返回任意一个处于二者之间的时间对象 Date 。
为了能在多线程环境中使用上面的上面的方法,我们使用线程安全的 ThreadLocalRandom
来生成随机数。
利用 Instant
Java 8 中添加的 java.time.Instant
是一个非常重要的关于时间的类,它提供了一个 ofEpochSecond()
方法可以便捷地将整数转换为时间:
public static Instant between(Instant start, Instant end) {
long startSeconds = start.getEpochSecond();
long endSeconds = end.getEpochSecond();
long random = ThreadLocalRandom
.current()
.nextLong(startSeconds, endSeconds);
return Instant.ofEpochSecond(random);
}
复制代码
上面方法入参是时间的开始点和结束点,返回在二者之间的时间。
利用 LocalDate 生成日期
在 Java 8 中,还增加了 LocalDate
这个时间类。
Random random = new Random();
int minDay = (int) LocalDate.of(1900, 1, 1).toEpochDay();
int maxDay = (int) LocalDate.of(2021, 7, 1).toEpochDay();
long randomDay = minDay + random.nextInt(maxDay - minDay);
LocalDate randomBirthDate = LocalDate.ofEpochDay(randomDay);
复制代码
上面的写法,可以更为直观地随机生成从 1990年1月1日到2021年7月1日的任意日期。
利用 LocalTime 生成时间
对于时间也应该在 00:00:00 到 23:59:59 范围内,所以我们可以简单地通过委托来实现这个逻辑:
public static LocalTime time() {
int randomTime = ThreadLocalRandom
.current()
.nextInt(LocalTime.MIN, LocalTime.MAX);
return LocalTime.ofSecondOfDay(randomTime);
}
复制代码
上面的方法可以随机生成从 00:00:00 到 23:59:59 任意时间值。
结束语
生成随机的代码不难写,但是思路转变很重要,如果刚开始就想着怎么生成类似 2021-07-05 12:30:45
这样的字符串,很可能陷入误区。
在实际项目开发中,我们可能很少遇到需要生成随机日期的场景。但是在某些需要 Mock 数据,测试某些特殊场景的时候,例如随机生日这种情形,上面的方法可能对你有所帮助。