如何在下午 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
.
来解决它
- 第一步将是:通过调用
LocalDate#atStartOfDay
获得 ZonedDateTime
ZoneId zoneId = ZoneId.systemDefault();
LocalDate.now().atStartOfDay(zoneId);
- 接下来,使用
ZonedDateTime#with
得到指定时间的ZonedDateTime
。
- 现在,您可以使用
ZonedDateTime#toInstant
从 ZonedDateTime
导出 Instant
。
- 以这种方式导出开始和结束
Instant
后,您可以使用 ThreadLocalRandom.current().nextLong
在开始和结束 [=] 范围内生成 long
值17=]s 并使用获取的值来获取所需的 Instant
.
- 最后,您可以使用
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);
}
}
了解有关现代日期时间 API 的更多信息
ONLINE DEMO随机打印100次
我试过使用-
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
.
- 第一步将是:通过调用
LocalDate#atStartOfDay
获得
ZonedDateTime
ZoneId zoneId = ZoneId.systemDefault();
LocalDate.now().atStartOfDay(zoneId);
- 接下来,使用
ZonedDateTime#with
得到指定时间的ZonedDateTime
。 - 现在,您可以使用
ZonedDateTime#toInstant
从ZonedDateTime
导出Instant
。 - 以这种方式导出开始和结束
Instant
后,您可以使用ThreadLocalRandom.current().nextLong
在开始和结束 [=] 范围内生成long
值17=]s 并使用获取的值来获取所需的Instant
. - 最后,您可以使用
Instant#atZone
and then get the required time usingZonedDateTime#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);
}
}
了解有关现代日期时间 API 的更多信息
ONLINE DEMO随机打印100次