Skip to content

Instantly share code, notes, and snippets.

@DreamTexX
Created September 2, 2023 09:53
Show Gist options
  • Save DreamTexX/68771bc0413e2d10d4e06988fb31020a to your computer and use it in GitHub Desktop.
Save DreamTexX/68771bc0413e2d10d4e06988fb31020a to your computer and use it in GitHub Desktop.
A simple svelte component to render a relative time in different languages using only web-apis.
<!-- src/lib/components/utils/LocalizedRelativeTime.svelte -->
<script lang="ts">
import { toRelativeLocalDate, toRelativeLocalDateWithUnit } from "$lib/intl/relative-time";
import { onMount } from "svelte";
export let date: Date;
export let language: string;
let { value, unitValue } = toRelativeLocalDateWithUnit(date, language);
let update: NodeJS.Timeout;
function runUpdate() {
update = setInterval(() => {
let intermediateValues = toRelativeLocalDateWithUnit(date, language);
value = intermediateValues.value;
if (intermediateValues.unitValue > unitValue) {
unitValue = intermediateValues.unitValue;
clearInterval(update);
runUpdate();
}
}, unitValue);
}
onMount(runUpdate);
</script>
<!-- TODO: consider if it should render a static, localized date when prerendering for SEO -->
{value}
// src/lib/intl/relative-time.ts
const units: Array<[Intl.RelativeTimeFormatUnit, number]> = [
["year", 24 * 60 * 60 * 1000 * 365],
["month", (24 * 60 * 60 * 1000 * 365) / 12],
["day", 24 * 60 * 60 * 1000],
["hour", 60 * 60 * 1000],
["minute", 60 * 1000],
["second", 1000]
];
export function toRelativeLocalDateWithUnit(
date: Date,
language: string
): { value: string; unit: Intl.RelativeTimeFormatUnit; unitValue: number } {
let formatter = new Intl.RelativeTimeFormat(language, { numeric: "auto" });
const elapsed = date.getTime() - new Date().getTime();
for (const [unit, value] of units) {
if (Math.abs(elapsed) > value) {
return {
value: formatter.format(Math.ceil(elapsed / value), unit),
unit,
unitValue: value
};
}
}
return {
value: formatter.format(Math.ceil(elapsed / 1000), "second"),
unit: "second",
unitValue: 1000
};
}
export function toRelativeLocalDate(date: Date, language: string): string {
return toRelativeLocalDateWithUnit(date, language).value;
}
<script lang="ts">
import LocalizedRelativeTime from "../utils/LocalizedRelativeTime.svelte";
export let language: string;
</script>
<div>
Component was rendered <LocalizedRelativeTime date={new Date()} {language} />
<br>
Komponente wurde <LocalizedRelativeTime date={new Date()} language="de-DE" /> erzeugt.
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment