Duration
使用 Effect 的 Duration 处理精确的时间跨度,支持创建、比较与算术运算,从而高效地处理时间。
Duration 数据类型表示非负的时间跨度。它常用于超时、延迟和调度,并提供针对不同时间单位的操作。
创建 Duration
Duration 模块提供了若干构造函数,用于以不同单位创建时长。
示例(以各种单位创建 Duration)
import { Duration } from "effect"
// Create a duration of 100 milliseconds
const duration1 = Duration.millis(100)
// Create a duration of 2 seconds
const duration2 = Duration.seconds(2)
// Create a duration of 5 minutes
const duration3 = Duration.minutes(5)
Duration.toMillis(duration3) // => 300000
你可以使用纳秒(nanoseconds)、微秒(microsecond)、毫秒(milliseconds)、秒(seconds)、分钟(minutes)、小时(hours)、天(days)和周(weeks)等单位创建 Duration。
若要表示无限时长,请使用 Duration.infinity。
示例(创建无限时长)
import { Duration } from "effect"
console.log(String(Duration.infinity))
String(Duration.infinity) // => "Infinity"
创建时长的另一种方式是使用 Duration.fromInputUnsafe 辅助函数:
number值会被视为毫秒。bigint值会被视为纳秒。- 字符串必须遵循
"${number} ${unit}"格式。
示例(将值解码为 Duration)
import { Duration } from "effect"
Duration.fromInputUnsafe(10n) // => Duration.nanos(10n)
Duration.fromInputUnsafe(100) // => Duration.millis(100)
Duration.fromInputUnsafe(Infinity) // => Duration.infinity
Duration.fromInputUnsafe("10 nanos") // => Duration.nanos(10n)
Duration.fromInputUnsafe("20 micros") // => Duration.micros(20n)
Duration.fromInputUnsafe("100 millis") // => Duration.millis(100)
Duration.fromInputUnsafe("2 seconds") // => Duration.seconds(2)
Duration.fromInputUnsafe("5 minutes") // => Duration.minutes(5)
Duration.fromInputUnsafe("7 hours") // => Duration.hours(7)
Duration.fromInputUnsafe("3 weeks") // => Duration.weeks(3)
获取 Duration 的值
你可以使用 Duration.toMillis 获取以毫秒表示的时长值。
示例(以毫秒获取 Duration)
import { Duration } from "effect"
console.log(Duration.toMillis(Duration.seconds(30)))
Duration.toMillis(Duration.seconds(30)) // => 30000
若要获取以纳秒表示的时长值,请使用 Duration.toNanos。注意 toNanos 返回 Option<bigint>,因为时长可能是无限的。
示例(以纳秒获取 Duration)
import { Duration, Option } from "effect"
console.log(Duration.toNanos(Duration.millis(100)))
Duration.toNanos(Duration.millis(100)) // => Option.some(100000000n)
若想直接得到 bigint 而不经过 Option,请使用 Duration.toNanosUnsafe。不过,对于无限的时长,它会抛出错误。
示例(不安全地获取纳秒值)
import { Duration } from "effect"
console.log(Duration.toNanosUnsafe(Duration.millis(100)))
// Output: 100000000n
console.log(Duration.toNanosUnsafe(Duration.infinity))
/*
throws:
Error: Cannot convert infinite duration to nanos
...stack trace...
*/
比较 Duration
使用以下函数比较两个 Duration:
| API | 说明 |
|---|---|
isLessThan | 如果第一个 Duration 小于第二个,则返回 true。 |
isLessThanOrEqualTo | 如果第一个 Duration 小于或等于第二个,则返回 true。 |
isGreaterThan | 如果第一个 Duration 大于第二个,则返回 true。 |
isGreaterThanOrEqualTo | 如果第一个 Duration 大于或等于第二个,则返回 true。 |
示例(比较两个 Duration)
import { Duration } from "effect"
const duration1 = Duration.seconds(30)
const duration2 = Duration.minutes(1)
console.log(Duration.isLessThan(duration1, duration2))
Duration.isLessThan(duration1, duration2) // => true
console.log(Duration.isLessThanOrEqualTo(duration1, duration2))
Duration.isLessThanOrEqualTo(duration1, duration2) // => true
console.log(Duration.isGreaterThan(duration1, duration2))
Duration.isGreaterThan(duration1, duration2) // => false
console.log(Duration.isGreaterThanOrEqualTo(duration1, duration2))
Duration.isGreaterThanOrEqualTo(duration1, duration2) // => false
执行算术运算
你可以对 Duration 执行算术运算,例如加法和乘法。
示例(对 Duration 做加法与乘法)
import { Duration } from "effect"
const duration1 = Duration.seconds(30)
const duration2 = Duration.minutes(1)
// Add two durations
console.log(String(Duration.sum(duration1, duration2)))
String(Duration.sum(duration1, duration2)) // => "90000 millis"
// Multiply a duration by a factor
console.log(String(Duration.times(duration1, 2)))
String(Duration.times(duration1, 2)) // => "60000 millis"
转换
将 Duration 转换为人类可读的字符串。
示例
import { Duration } from "effect"
Duration.format(Duration.millis(1000)) // => "1s"
Duration.format(Duration.millis(1001)) // => "1s 1ms"