@@ -95,27 +95,80 @@ export function applyDuration(date: Date | number, duration: Duration): Date {
95
95
return r
96
96
}
97
97
98
- export function elapsedTime ( date : Date , precision : Unit = 'second' , now = Date . now ( ) ) : Duration {
99
- const delta = date . getTime ( ) - now
100
- if ( delta === 0 ) return new Duration ( )
101
- const sign = Math . sign ( delta )
102
- const ms = Math . abs ( delta )
103
- const sec = Math . floor ( ms / 1000 )
104
- const min = Math . floor ( sec / 60 )
105
- const hr = Math . floor ( min / 60 )
106
- const day = Math . floor ( hr / 24 )
107
- const month = Math . floor ( day / 30 )
108
- const year = Math . floor ( month / 12 )
109
- const i = unitNames . indexOf ( precision ) || unitNames . length
98
+ // Calculates the elapsed time from `now` to `date`.
99
+ export function elapsedTime (
100
+ date : Date ,
101
+ precision : Unit = 'second' ,
102
+ nowTimestamp : Date | number = Date . now ( ) ,
103
+ ) : Duration {
104
+ const now = new Date ( nowTimestamp )
105
+ // eslint-disable-next-line prefer-const
106
+ let [ sign , subtrahend , minuend ] = date < now ? [ - 1 , now , date ] : [ 1 , date , now ]
107
+ let ms : number
108
+ let sec : number
109
+ let min : number
110
+ let hr : number
111
+ let day : number
112
+ let month : number
113
+ let year : number
114
+ // Using UTC to avoid timezone-specific variations.
115
+ if ( subtrahend . getUTCMilliseconds ( ) >= minuend . getUTCMilliseconds ( ) ) {
116
+ ms = subtrahend . getUTCMilliseconds ( ) - minuend . getUTCMilliseconds ( )
117
+ } else {
118
+ ms = 1000 + subtrahend . getUTCMilliseconds ( ) - minuend . getUTCMilliseconds ( )
119
+ subtrahend = new Date ( subtrahend . getTime ( ) - 1000 )
120
+ }
121
+
122
+ if ( subtrahend . getUTCSeconds ( ) >= minuend . getUTCSeconds ( ) ) {
123
+ sec = subtrahend . getUTCSeconds ( ) - minuend . getUTCSeconds ( )
124
+ } else {
125
+ sec = 60 + subtrahend . getUTCSeconds ( ) - minuend . getUTCSeconds ( )
126
+ subtrahend = new Date ( subtrahend . getTime ( ) - 1000 * 60 )
127
+ }
128
+
129
+ if ( subtrahend . getUTCMinutes ( ) >= minuend . getUTCMinutes ( ) ) {
130
+ min = subtrahend . getUTCMinutes ( ) - minuend . getUTCMinutes ( )
131
+ } else {
132
+ min = 60 + subtrahend . getUTCMinutes ( ) - minuend . getUTCMinutes ( )
133
+ subtrahend = new Date ( subtrahend . getTime ( ) - 1000 * 60 * 60 )
134
+ }
135
+
136
+ if ( subtrahend . getUTCHours ( ) >= minuend . getUTCHours ( ) ) {
137
+ hr = subtrahend . getUTCHours ( ) - minuend . getUTCHours ( )
138
+ } else {
139
+ hr = 24 + subtrahend . getUTCHours ( ) - minuend . getUTCHours ( )
140
+ subtrahend = new Date ( subtrahend . getTime ( ) - 1000 * 60 * 60 * 24 )
141
+ }
142
+
143
+ if ( subtrahend . getUTCDate ( ) >= minuend . getUTCDate ( ) ) {
144
+ day = subtrahend . getUTCDate ( ) - minuend . getUTCDate ( )
145
+ } else {
146
+ day = subtrahend . getUTCDate ( )
147
+ subtrahend = new Date ( subtrahend . getTime ( ) - 1000 * 60 * 60 * 24 * day )
148
+ day += Math . max ( 0 , subtrahend . getUTCDate ( ) - minuend . getUTCDate ( ) )
149
+ }
150
+
151
+ year = subtrahend . getUTCFullYear ( ) - minuend . getUTCFullYear ( )
152
+ if ( subtrahend . getUTCMonth ( ) >= minuend . getUTCMonth ( ) ) {
153
+ month = subtrahend . getUTCMonth ( ) - minuend . getUTCMonth ( )
154
+ } else {
155
+ month = 12 + subtrahend . getUTCMonth ( ) - minuend . getUTCMonth ( )
156
+ year -= 1
157
+ }
158
+
159
+ let precisionIndex = unitNames . indexOf ( precision )
160
+ if ( precisionIndex === - 1 ) {
161
+ precisionIndex = unitNames . length
162
+ }
110
163
return new Duration (
111
- i >= 0 ? year * sign : 0 ,
112
- i >= 1 ? ( month - year * 12 ) * sign : 0 ,
164
+ precisionIndex >= 0 ? year * sign : 0 ,
165
+ precisionIndex >= 1 ? month * sign : 0 ,
113
166
0 ,
114
- i >= 3 ? ( day - month * 30 ) * sign : 0 ,
115
- i >= 4 ? ( hr - day * 24 ) * sign : 0 ,
116
- i >= 5 ? ( min - hr * 60 ) * sign : 0 ,
117
- i >= 6 ? ( sec - min * 60 ) * sign : 0 ,
118
- i >= 7 ? ( ms - sec * 1000 ) * sign : 0 ,
167
+ precisionIndex >= 3 ? day * sign : 0 ,
168
+ precisionIndex >= 4 ? hr * sign : 0 ,
169
+ precisionIndex >= 5 ? min * sign : 0 ,
170
+ precisionIndex >= 6 ? sec * sign : 0 ,
171
+ precisionIndex >= 7 ? ms * sign : 0 ,
119
172
)
120
173
}
121
174
0 commit comments