「现在几点」是测试里最难控制的隐式输入。这篇用真实运行把 Clock 的几种实现、注入后能省多少测试时间、以及固定时钟时容易漏掉的时区与分辨率问题逐个验证。
[kinds]
fixed: 两次 instant() 相同? true → 2026-03-08T01:59:59.987654321Z
offset(fixed, +90s): 2026-03-08T02:01:29.987654321Z
tickSeconds(fixed): TickClock / 对 fixed 取整: 2026-03-08T01:59:59Z
tickMillis(fixed): 2026-03-08T01:59:59.987Z
tickMinutes(fixed): 2026-03-08T01:59:00Z
tick(PT1.5S):正常,instant() = 2026-03-08T01:59:58.500Z
tick(PT0.3S):正常,instant() = 2026-03-08T01:59:59.700Z
tick(PT0.000000003S):IllegalArgumentException: Invalid tick duration
tick(PT0.0000015S):IllegalArgumentException: Invalid tick duration
tick(PT0S):正常,instant() = 2026-03-08T01:59:59.987654321Z
tick(PT-1S):IllegalArgumentException: Tick duration must not be negative
systemUTC / systemDefaultZone 的时区: Z / Asia/Shanghai
toString: FixedClock[2026-03-08T01:59:59.987654321Z,Z] | OffsetClock[FixedClock[2026-03-08T01:59:59.987654321Z,Z],PT1S] | TickClock[SystemClock[Z],PT1S] [expiry]
签发后:valid=true
29:59 之后:valid=true
30:00 整:valid=false(isBefore 是严格小于,恰好到期就失效)
一年之后:valid=false
可变时钟版本的整个测试耗时 3.38 ms
真实时钟版本:TTL 1200 ms,sleep 1250 ms 之后 valid=false,测试耗时 1254 ms [-Duser.timezone=UTC]
默认时区 UTC;Legacy.today()(当前系统时间) = 2026-10-03
同一个固定瞬间 2026-06-30T20:30:00Z,不同 zone 的 LocalDate:
UTC 2026-06-30
Asia/Shanghai 2026-07-01
America/Los_Angeles 2026-06-30
Pacific/Kiritimati 2026-07-01
Clock.fixed(at, systemDefault) 的结果随默认时区而变:2026-06-30
[-Duser.timezone=Asia/Shanghai]
默认时区 Asia/Shanghai;Legacy.today()(当前系统时间) = 2026-10-04
同一个固定瞬间 2026-06-30T20:30:00Z,不同 zone 的 LocalDate:
UTC 2026-06-30
Asia/Shanghai 2026-07-01
America/Los_Angeles 2026-06-30
Pacific/Kiritimati 2026-07-01
Clock.fixed(at, systemDefault) 的结果随默认时区而变:2026-07-01
[-Duser.timezone=America/Los_Angeles]
默认时区 America/Los_Angeles;Legacy.today()(当前系统时间) = 2026-10-03
同一个固定瞬间 2026-06-30T20:30:00Z,不同 zone 的 LocalDate:
UTC 2026-06-30
Asia/Shanghai 2026-07-01
America/Los_Angeles 2026-06-30
Pacific/Kiritimati 2026-07-01
Clock.fixed(at, systemDefault) 的结果随默认时区而变:2026-06-30 [precision]
Instant.now() 的纳秒数 mod 1000 在 20000 次采样里有 1 种取值(只有 0 说明分辨率是微秒或更粗):[0]
同样统计微秒位(纳秒 % 1e6 / 1000)有 999 种取值
System.nanoTime() 相邻两次不同读数的最小差:41 ns [tick]
tickSeconds 在 2.5 秒里的 125 次读数共有 4 种不同的值,最小间隔为 PT1S,每个值的纳秒部分都是 0:true
tick(100 ms) 在 1 秒里有 11 种不同的值;全部是 100 ms 的整数倍:true [wall]
模拟系统时间在 200 ms 内被回拨 2 秒:Duration.between(开始, 结束)(基于 Clock) = PT-2S;基于 System.nanoTime 的耗时 = 205 ms
(这是用可变时钟模拟的回拨,没有真的改系统时间)