@@ -119,8 +119,14 @@ export function elapsedTime(date: Date, precision: Unit = 'second', now = Date.n
119
119
)
120
120
}
121
121
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 )
123
128
if ( duration . blank ) return duration
129
+ const sign = duration . sign
124
130
let years = Math . abs ( duration . years )
125
131
let months = Math . abs ( duration . months )
126
132
let weeks = Math . abs ( duration . weeks )
@@ -131,7 +137,9 @@ export function roundToSingleUnit(duration: Duration): Duration {
131
137
let milliseconds = Math . abs ( duration . milliseconds )
132
138
133
139
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
+ }
135
143
136
144
if ( seconds >= 55 ) minutes += Math . round ( seconds / 60 )
137
145
if ( minutes || hours || days || weeks || months || years ) seconds = 0
@@ -148,10 +156,17 @@ export function roundToSingleUnit(duration: Duration): Duration {
148
156
if ( weeks >= 4 ) months += Math . round ( weeks / 4 )
149
157
if ( months || years ) weeks = 0
150
158
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
+ }
152
168
if ( years ) months = 0
153
169
154
- const sign = duration . sign
155
170
return new Duration (
156
171
years * sign ,
157
172
months * sign ,
@@ -164,8 +179,11 @@ export function roundToSingleUnit(duration: Duration): Duration {
164
179
)
165
180
}
166
181
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 )
169
187
if ( rounded . blank ) return [ 0 , 'second' ]
170
188
for ( const unit of unitNames ) {
171
189
if ( unit === 'millisecond' ) continue
0 commit comments