Files
brave-core/components/common/useRelativeTime.ts
T

59 lines
1.7 KiB
TypeScript

// Copyright (c) 2024 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
import { useEffect, useState } from "react"
// Set numeric to auto so we get 'yesterday' instead of '1 day ago'
const rtf = new Intl.RelativeTimeFormat(undefined, {
numeric: 'auto'
})
const second = 1000
const minute = 60 * second
const hour = 60 * minute
const day = 24 * hour
const week = 7 * day
const year = 365 * day
const durations = {
second, minute, hour, day, week, year
}
// Formats a time relative to now as the rounded number of units.
export const getRelativeTime = (time: Date | number) => {
const now = Date.now()
const then = new Date(time).getTime()
const diff = then - now
const [unit, duration] = (Object.entries(durations) as any).findLast(([, duration]: [string, number]) => Math.abs(diff) > duration) ?? ['second', 1000]
const amount = Math.floor(diff / duration)
return {
formatted: rtf.format(amount, unit ),
updatesIn: Math.max(10 * minute, duration - (Math.abs(diff - amount))),
}
}
export default function useRelativeTime(time: Date | number) {
const [formatted, setFormatted] = useState('')
useEffect(() => {
if (!time) return
let timeout: NodeJS.Timeout
const update = () => {
const { formatted, updatesIn } = getRelativeTime(time)
setFormatted(formatted)
timeout = setTimeout(update, updatesIn)
}
update()
return () => {
clearTimeout(timeout)
}
}, [time])
return formatted
}