Skip to content

Commit 70ccf67

Browse files
committed
update rounding rules for months/years in Duration
1 parent 9388664 commit 70ccf67

File tree

3 files changed

+318
-64
lines changed

3 files changed

+318
-64
lines changed

src/duration.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,14 @@ export function elapsedTime(date: Date, precision: Unit = 'second', now = Date.n
119119
)
120120
}
121121

122-
export function roundToSingleUnit(duration: Duration): Duration {
122+
interface RoundingOpts {
123+
relativeTo: Date | number
124+
}
125+
126+
export function roundToSingleUnit(duration: Duration, {relativeTo = Date.now()}: Partial<RoundingOpts> = {}): Duration {
127+
relativeTo = new Date(relativeTo)
123128
if (duration.blank) return duration
129+
const sign = duration.sign
124130
let years = Math.abs(duration.years)
125131
let months = Math.abs(duration.months)
126132
let weeks = Math.abs(duration.weeks)
@@ -131,7 +137,9 @@ export function roundToSingleUnit(duration: Duration): Duration {
131137
let milliseconds = Math.abs(duration.milliseconds)
132138

133139
if (milliseconds >= 900) seconds += Math.round(milliseconds / 1000)
134-
if (seconds || minutes || hours || days || weeks || months || years) milliseconds = 0
140+
if (seconds || minutes || hours || days || weeks || months || years) {
141+
milliseconds = 0
142+
}
135143

136144
if (seconds >= 55) minutes += Math.round(seconds / 60)
137145
if (minutes || hours || days || weeks || months || years) seconds = 0
@@ -148,10 +156,17 @@ export function roundToSingleUnit(duration: Duration): Duration {
148156
if (weeks >= 4) months += Math.round(weeks / 4)
149157
if (months || years) weeks = 0
150158

151-
if (months >= 11) years += Math.round(months / 12)
159+
const currentMonth = relativeTo.getMonth()
160+
const delta = sign < 0 ? currentMonth : 12 - currentMonth
161+
if (months && months >= delta) {
162+
years += 1
163+
relativeTo.setFullYear(relativeTo.getFullYear() + sign)
164+
relativeTo.setMonth(0)
165+
months -= delta
166+
years += Math.floor(months / 12)
167+
}
152168
if (years) months = 0
153169

154-
const sign = duration.sign
155170
return new Duration(
156171
years * sign,
157172
months * sign,
@@ -164,8 +179,11 @@ export function roundToSingleUnit(duration: Duration): Duration {
164179
)
165180
}
166181

167-
export function getRelativeTimeUnit(duration: Duration): [number, Intl.RelativeTimeFormatUnit] {
168-
const rounded = roundToSingleUnit(duration)
182+
export function getRelativeTimeUnit(
183+
duration: Duration,
184+
opts?: Partial<RoundingOpts>,
185+
): [number, Intl.RelativeTimeFormatUnit] {
186+
const rounded = roundToSingleUnit(duration, opts)
169187
if (rounded.blank) return [0, 'second']
170188
for (const unit of unitNames) {
171189
if (unit === 'millisecond') continue

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy