(duration: Duration, {relativeTo = Date.now()}: Partial<RoundingOpts> = {})
| 133 | } |
| 134 | |
| 135 | export function roundToSingleUnit(duration: Duration, {relativeTo = Date.now()}: Partial<RoundingOpts> = {}): Duration { |
| 136 | relativeTo = new Date(relativeTo) |
| 137 | if (duration.blank) return duration |
| 138 | const sign = duration.sign |
| 139 | let years = Math.abs(duration.years) |
| 140 | let months = Math.abs(duration.months) |
| 141 | let weeks = Math.abs(duration.weeks) |
| 142 | let days = Math.abs(duration.days) |
| 143 | let hours = Math.abs(duration.hours) |
| 144 | let minutes = Math.abs(duration.minutes) |
| 145 | let seconds = Math.abs(duration.seconds) |
| 146 | let milliseconds = Math.abs(duration.milliseconds) |
| 147 | |
| 148 | if (milliseconds >= 900) seconds += Math.round(milliseconds / 1000) |
| 149 | if (seconds || minutes || hours || days || weeks || months || years) { |
| 150 | milliseconds = 0 |
| 151 | } |
| 152 | |
| 153 | if (seconds >= 55) minutes += Math.round(seconds / 60) |
| 154 | if (minutes || hours || days || weeks || months || years) seconds = 0 |
| 155 | |
| 156 | if (minutes >= 55) hours += Math.round(minutes / 60) |
| 157 | if (hours || days || weeks || months || years) minutes = 0 |
| 158 | |
| 159 | if (days && hours >= 12) days += Math.round(hours / 24) |
| 160 | if (!days && hours >= 21) days += Math.round(hours / 24) |
| 161 | if (days || weeks || months || years) hours = 0 |
| 162 | |
| 163 | // Resolve calendar dates |
| 164 | const currentYear = relativeTo.getFullYear() |
| 165 | const currentMonth = relativeTo.getMonth() |
| 166 | const currentDate = relativeTo.getDate() |
| 167 | if (days >= 27 || years + months + days) { |
| 168 | const newMonthDate = new Date(relativeTo) |
| 169 | newMonthDate.setDate(1) |
| 170 | newMonthDate.setMonth(currentMonth + months * sign + 1) |
| 171 | newMonthDate.setDate(0) |
| 172 | const monthDateCorrection = Math.max(0, currentDate - newMonthDate.getDate()) |
| 173 | |
| 174 | const newDate = new Date(relativeTo) |
| 175 | newDate.setFullYear(currentYear + years * sign) |
| 176 | newDate.setDate(currentDate - monthDateCorrection) |
| 177 | newDate.setMonth(currentMonth + months * sign) |
| 178 | newDate.setDate(currentDate - monthDateCorrection + days * sign) |
| 179 | const yearDiff = newDate.getFullYear() - relativeTo.getFullYear() |
| 180 | const monthDiff = newDate.getMonth() - relativeTo.getMonth() |
| 181 | const daysDiff = Math.abs(Math.round((Number(newDate) - Number(relativeTo)) / 86400000)) + monthDateCorrection |
| 182 | const monthsDiff = Math.abs(yearDiff * 12 + monthDiff) |
| 183 | if (daysDiff < 27) { |
| 184 | if (days >= 6) { |
| 185 | weeks += Math.round(days / 7) |
| 186 | days = 0 |
| 187 | } else { |
| 188 | days = daysDiff |
| 189 | } |
| 190 | months = years = 0 |
| 191 | } else if (monthsDiff <= 11) { |
| 192 | months = monthsDiff |
no test coverage detected
searching dependent graphs…