An ATproto social media client -- with an independent Appview.

get a little more accurate with month length (#3981)

* get a little more accurate with month length

* create some wiggle room, create some specific tests

* update more tests

authored by hailey.at and committed by GitHub 5cd4ac3a 73d094c6

Changed files
+57 -6
__tests__
src
lib
strings
+42
__tests__/lib/string.test.ts
··· 143 143 }) 144 144 145 145 describe('ago', () => { 146 + const oneYearDate = new Date( 147 + new Date().setMonth(new Date().getMonth() - 11), 148 + ).setDate(new Date().getDate() - 28) 149 + 146 150 const inputs = [ 147 151 1671461038, 148 152 '04 Dec 1995 00:12:00 GMT', ··· 151 155 new Date().setMinutes(new Date().getMinutes() - 10), 152 156 new Date().setHours(new Date().getHours() - 1), 153 157 new Date().setDate(new Date().getDate() - 1), 158 + new Date().setDate(new Date().getDate() - 20), 159 + new Date().setDate(new Date().getDate() - 25), 160 + new Date().setDate(new Date().getDate() - 28), 161 + new Date().setDate(new Date().getDate() - 29), 162 + new Date().setDate(new Date().getDate() - 30), 154 163 new Date().setMonth(new Date().getMonth() - 1), 164 + new Date(new Date().setMonth(new Date().getMonth() - 1)).setDate( 165 + new Date().getDate() - 20, 166 + ), 167 + new Date(new Date().setMonth(new Date().getMonth() - 1)).setDate( 168 + new Date().getDate() - 25, 169 + ), 170 + new Date(new Date().setMonth(new Date().getMonth() - 1)).setDate( 171 + new Date().getDate() - 28, 172 + ), 173 + new Date(new Date().setMonth(new Date().getMonth() - 1)).setDate( 174 + new Date().getDate() - 29, 175 + ), 176 + new Date().setMonth(new Date().getMonth() - 11), 177 + new Date(new Date().setMonth(new Date().getMonth() - 11)).setDate( 178 + new Date().getDate() - 20, 179 + ), 180 + new Date(new Date().setMonth(new Date().getMonth() - 11)).setDate( 181 + new Date().getDate() - 25, 182 + ), 183 + oneYearDate, 155 184 ] 156 185 const outputs = [ 157 186 new Date(1671461038).toLocaleDateString(), ··· 161 190 '10m', 162 191 '1h', 163 192 '1d', 193 + '20d', 194 + '25d', 195 + '28d', 196 + '29d', 164 197 '1mo', 198 + '1mo', 199 + '1mo', 200 + '1mo', 201 + '2mo', 202 + '2mo', 203 + '11mo', 204 + '11mo', 205 + '11mo', 206 + new Date(oneYearDate).toLocaleDateString(), 165 207 ] 166 208 167 209 it('correctly calculates how much time passed, in a string', () => {
+15 -6
src/lib/strings/time.ts
··· 2 2 const MINUTE = 60 3 3 const HOUR = MINUTE * 60 4 4 const DAY = HOUR * 24 5 - const MONTH = DAY * 28 6 - const YEAR = DAY * 365 5 + const MONTH_30 = DAY * 30 6 + const MONTH = DAY * 30.41675 // This results in 365.001 days in a year, which is close enough for nearly all cases 7 7 export function ago(date: number | string | Date): string { 8 8 let ts: number 9 9 if (typeof date === 'string') { ··· 22 22 return `${Math.floor(diffSeconds / MINUTE)}m` 23 23 } else if (diffSeconds < DAY) { 24 24 return `${Math.floor(diffSeconds / HOUR)}h` 25 - } else if (diffSeconds < MONTH) { 25 + } else if (diffSeconds < MONTH_30) { 26 26 return `${Math.round(diffSeconds / DAY)}d` 27 - } else if (diffSeconds < YEAR) { 28 - return `${Math.floor(diffSeconds / MONTH)}mo` 29 27 } else { 30 - return new Date(ts).toLocaleDateString() 28 + let months = diffSeconds / MONTH 29 + if (months % 1 >= 0.9) { 30 + months = Math.ceil(months) 31 + } else { 32 + months = Math.floor(months) 33 + } 34 + 35 + if (months < 12) { 36 + return `${months}mo` 37 + } else { 38 + return new Date(ts).toLocaleDateString() 39 + } 31 40 } 32 41 } 33 42