Coves frontend - a photon fork
1<script lang="ts" module>
2 import { locale } from '$lib/app/i18n'
3 import { settings } from '$lib/app/settings.svelte'
4
5 export function formatRelativeDate(
6 date: Date,
7 options: Intl.RelativeTimeFormatOptions,
8 locale?: string,
9 relativeTo?: Date,
10 ) {
11 try {
12 const now = relativeTo?.getTime() ?? Date.now()
13
14 const diffInMillis = now - date.getTime()
15
16 const thresholds = [
17 { unit: 'second', threshold: 1000 },
18 { unit: 'minute', threshold: 60 * 1000 },
19 { unit: 'hour', threshold: 60 * 60 * 1000 },
20 { unit: 'day', threshold: 24 * 60 * 60 * 1000 },
21 { unit: 'week', threshold: 7 * 24 * 60 * 60 * 1000 },
22 { unit: 'month', threshold: 30 * 24 * 60 * 60 * 1000 },
23 { unit: 'year', threshold: 365 * 24 * 60 * 60 * 1000 },
24 ]
25
26 for (let i = thresholds.length - 1; i >= 0; i--) {
27 if (diffInMillis >= thresholds[i].threshold) {
28 const value = Math.round(diffInMillis / thresholds[i].threshold)
29
30 let language = locale ?? 'en'
31
32 if (settings.absoluteDates) {
33 const rtf = new Intl.DateTimeFormat(language, {
34 ...options,
35 timeStyle: 'short',
36 dateStyle: 'short',
37 })
38 return rtf.format(date)
39 } else {
40 const rtf = new Intl.RelativeTimeFormat(language, options)
41 return rtf.format(-value, thresholds[i].unit as 'second')
42 }
43 }
44 }
45 return 'Now'
46 } catch {
47 return 'Invalid Date'
48 }
49 }
50</script>
51
52<script lang="ts">
53 const toLocaleDateString = (date: Date): string => {
54 try {
55 return date.toLocaleString()
56 } catch {
57 return 'Invalid Date'
58 }
59 }
60
61 interface Props {
62 date: Date
63 relativeTo?: Date | undefined
64 options?: Intl.RelativeTimeFormatOptions
65 style?: string
66 class?: string
67 }
68
69 let {
70 date,
71 relativeTo = undefined,
72 options = {
73 numeric: 'always',
74 style: 'narrow',
75 },
76 style = '',
77 class: clazz = '',
78 }: Props = $props()
79
80 let dateTime = $derived(toLocaleDateString(date))
81</script>
82
83<time datetime={dateTime} title={dateTime} class={clazz} {style}>
84 {formatRelativeDate(date, options, $locale, relativeTo)}
85</time>