如何在下午 4 点和凌晨 2 点之间的两个时间之间生成随机时间?

How to generate a random time between two times say 4PM and 2AM?

我试过使用-

int startSeconds = restaurant.openingTime.toSecondOfDay();
int endSeconds = restaurant.closingTime.toSecondOfDay();
LocalTime timeBetweenOpenClose = LocalTime.ofSecondOfDay(ThreadLocalRandom.current().nextInt(startSeconds, endSeconds));

但这通常会遇到错误,如 nextInt(origin, bounds),origin 不能小于边界,如果我的 openingTime 是 16:00:00 和 closingTime 是 02:00:00.

startSeconds大于endSeconds时,您可以加上一天的秒数(24*60*60)来表示第二天的秒数,然后得到一个随机数对它取模一天的秒数,通过有效的秒值将其转换为 LocalTime。

int secondsInDay = (int)Duration.ofDays(1).getSeconds();
if(startSeconds > endSeconds){
  endSeconds += secondsInDay;
}
LocalTime timeBetweenOpenClose = LocalTime.ofSecondOfDay(
              ThreadLocalRandom.current().nextInt(startSeconds, endSeconds) % secondsInDay);

如果不应用日期和时区,我们无法知道下午 4 点到凌晨 2 点之间会经过多少时间。因此,我们将使用ZonedDateTime.

来解决它
  1. 第一步将是:通过调用 LocalDate#atStartOfDay
  2. 获得 ZonedDateTime
ZoneId zoneId = ZoneId.systemDefault();
LocalDate.now().atStartOfDay(zoneId);
  1. 接下来,使用ZonedDateTime#with得到指定时间的ZonedDateTime
  2. 现在,您可以使用 ZonedDateTime#toInstantZonedDateTime 导出 Instant
  3. 以这种方式导出开始和结束 Instant 后,您可以使用 ThreadLocalRandom.current().nextLong 在开始和结束 [=] 范围内生成 long 值17=]s 并使用获取的值来获取所需的 Instant.
  4. 最后,您可以使用 Instant#atZone and then get the required time using ZonedDateTime#toLocalTime 从这个 Instant 导出 ZonedDateTime

演示:

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.concurrent.ThreadLocalRandom;

public class Main {
    public static void main(String[] args) {
        // Change it as per the applicable timezone e.g. ZoneId.of("Europe/London")
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDate today = LocalDate.now();
        
        ZonedDateTime zdtStart = today.atStartOfDay(zoneId)
                                      .with(LocalTime.of(16, 0));
        
        ZonedDateTime zdtEnd = today.plusDays(1)
                                    .atStartOfDay(zoneId)
                                    .with(LocalTime.of(2, 0));
        
        ZonedDateTime zdtResult = 
                Instant.ofEpochMilli(
                            ThreadLocalRandom
                            .current()
                            .nextLong(
                                        zdtStart.toInstant().toEpochMilli(), 
                                        zdtEnd.toInstant().toEpochMilli()
                                    )
                        ).atZone(zoneId);
        
        LocalTime time = zdtResult.toLocalTime();
        System.out.println(time);
    }
}

Trail: Date Time.

了解有关现代日期时间 API 的更多信息

ONLINE DEMO随机打印100次