@@ -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