Skip to content

Commit 3336287

Browse files
authoredMar 25, 2024··
add Duration.subtract api (#2402)
1 parent 47a8f1b commit 3336287

File tree

4 files changed

+59
-18
lines changed

4 files changed

+59
-18
lines changed
 

‎.changeset/fuzzy-bats-thank.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect": patch
3+
---
4+
5+
add Duration.subtract api

‎.changeset/swift-hats-cry.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect": patch
3+
---
4+
5+
remove use of bigint literals in Duration

‎packages/effect/src/Duration.ts

+38-18
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ import { hasProperty, isBigInt, isNumber } from "./Predicate.js"
1515

1616
const TypeId: unique symbol = Symbol.for("effect/Duration")
1717

18+
const bigint0 = BigInt(0)
19+
const bigint24 = BigInt(24)
20+
const bigint60 = BigInt(60)
1821
const bigint1e3 = BigInt(1_000)
22+
const bigint1e6 = BigInt(1_000_000)
1923
const bigint1e9 = BigInt(1_000_000_000)
2024

2125
/**
@@ -162,7 +166,7 @@ const DurationProto: Omit<Duration, "value"> = {
162166
const make = (input: number | bigint): Duration => {
163167
const duration = Object.create(DurationProto)
164168
if (isNumber(input)) {
165-
if (isNaN(input) || input < 0) {
169+
if (isNaN(input) || input <= 0) {
166170
duration.value = zeroValue
167171
} else if (!Number.isFinite(input)) {
168172
duration.value = infinityValue
@@ -171,7 +175,7 @@ const make = (input: number | bigint): Duration => {
171175
} else {
172176
duration.value = { _tag: "Millis", millis: input }
173177
}
174-
} else if (input < BigInt(0)) {
178+
} else if (input <= bigint0) {
175179
duration.value = zeroValue
176180
} else {
177181
duration.value = { _tag: "Nanos", nanos: input }
@@ -522,6 +526,22 @@ export const times: {
522526
})
523527
)
524528

529+
/**
530+
* @since 2.0.0
531+
* @category math
532+
*/
533+
export const subtract: {
534+
(that: DurationInput): (self: DurationInput) => Duration
535+
(self: DurationInput, that: DurationInput): Duration
536+
} = dual(
537+
2,
538+
(self: DurationInput, that: DurationInput): Duration =>
539+
matchWith(self, that, {
540+
onMillis: (self, that) => make(self - that),
541+
onNanos: (self, that) => make(self - that)
542+
})
543+
)
544+
525545
/**
526546
* @since 2.0.0
527547
* @category math
@@ -631,32 +651,32 @@ export const format = (self: DurationInput): string => {
631651

632652
const nanos = unsafeToNanos(duration)
633653

634-
if (nanos % 1000000n) {
635-
parts.push(`${nanos % 1000000n}ns`)
654+
if (nanos % bigint1e6) {
655+
parts.push(`${nanos % bigint1e6}ns`)
636656
}
637657

638-
const ms = nanos / 1000000n
639-
if (ms % 1000n !== 0n) {
640-
parts.push(`${ms % 1000n}ms`)
658+
const ms = nanos / bigint1e6
659+
if (ms % bigint1e3 !== bigint0) {
660+
parts.push(`${ms % bigint1e3}ms`)
641661
}
642662

643-
const sec = ms / 1000n
644-
if (sec % 60n !== 0n) {
645-
parts.push(`${sec % 60n}s`)
663+
const sec = ms / bigint1e3
664+
if (sec % bigint60 !== bigint0) {
665+
parts.push(`${sec % bigint60}s`)
646666
}
647667

648-
const min = sec / 60n
649-
if (min % 60n !== 0n) {
650-
parts.push(`${min % 60n}m`)
668+
const min = sec / bigint60
669+
if (min % bigint60 !== bigint0) {
670+
parts.push(`${min % bigint60}m`)
651671
}
652672

653-
const hr = min / 60n
654-
if (hr % 24n !== 0n) {
655-
parts.push(`${hr % 24n}h`)
673+
const hr = min / bigint60
674+
if (hr % bigint24 !== bigint0) {
675+
parts.push(`${hr % bigint24}h`)
656676
}
657677

658-
const days = hr / 24n
659-
if (days !== 0n) {
678+
const days = hr / bigint24
679+
if (days !== bigint0) {
660680
parts.push(`${days}d`)
661681
}
662682

‎packages/effect/test/Duration.test.ts

+11
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,17 @@ describe("Duration", () => {
141141
expect(Duration.sum("30 seconds", "30 seconds")).toEqual(Duration.minutes(1))
142142
})
143143

144+
it("subtract", () => {
145+
expect(Duration.subtract(Duration.seconds(30), Duration.seconds(10))).toEqual(Duration.seconds(20))
146+
expect(Duration.subtract(Duration.seconds(30), Duration.seconds(30))).toEqual(Duration.zero)
147+
expect(Duration.subtract(Duration.nanos(30n), Duration.nanos(10n))).toEqual(Duration.nanos(20n))
148+
expect(Duration.subtract(Duration.nanos(30n), Duration.nanos(30n))).toEqual(Duration.zero)
149+
expect(Duration.subtract(Duration.seconds(Infinity), Duration.seconds(30))).toEqual(Duration.seconds(Infinity))
150+
expect(Duration.subtract(Duration.seconds(30), Duration.seconds(Infinity))).toEqual(Duration.zero)
151+
152+
expect(Duration.subtract("30 seconds", "10 seconds")).toEqual(Duration.seconds(20))
153+
})
154+
144155
it("greaterThan", () => {
145156
assert.isTrue(pipe(Duration.seconds(30), Duration.greaterThan(Duration.seconds(20))))
146157
assert.isFalse(pipe(Duration.seconds(30), Duration.greaterThan(Duration.seconds(30))))

0 commit comments

Comments
 (0)
Please sign in to comment.