Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 27x 27x 30x 27x 27x 27x 27x 34x 14x 547x 547x 540x 2x 538x 1x 537x 2x 535x 1x 534x 1x 533x 26x 507x 533x 1x 1x 25x 506x 534x 534x 534x 534x 534x 1x 533x | import { TFunction } from "i18next";
export const secondMillis = 1000;
export const minuteMillis = 60 * secondMillis;
export const hourMillis = 60 * minuteMillis;
export const dayMillis = 24 * hourMillis;
export const weekMillis = 7 * dayMillis;
export const monthMillis = 30 * dayMillis;
export const yearMillis = 365 * dayMillis + 6 * hourMillis; // 365.25;
interface FuzzySpecT {
millis: number;
translationKey: Parameters<TFunction<"global", undefined>>[0];
}
export enum TimeUnit {
Seconds,
Minutes,
Hours,
Days,
Weeks,
Months,
Years,
}
/// A time span represented in human-friendly units, e.g. "5 days".
export class FriendlyTimeSpan {
constructor(
public value: number,
public unit: TimeUnit,
) {}
static fromMillis(value: number): FriendlyTimeSpan {
if (value < minuteMillis) {
return new FriendlyTimeSpan(Math.floor(value / 1000), TimeUnit.Seconds);
}
if (value < hourMillis) {
return new FriendlyTimeSpan(
Math.floor(value / minuteMillis),
TimeUnit.Minutes,
);
}
if (value < dayMillis) {
return new FriendlyTimeSpan(
Math.floor(value / hourMillis),
TimeUnit.Hours,
);
}
if (value < weekMillis) {
return new FriendlyTimeSpan(Math.floor(value / dayMillis), TimeUnit.Days);
}
if (value < monthMillis) {
return new FriendlyTimeSpan(
Math.floor(value / weekMillis),
TimeUnit.Weeks,
);
}
if (value < yearMillis) {
return new FriendlyTimeSpan(
Math.floor(value / monthMillis),
TimeUnit.Months,
);
}
return new FriendlyTimeSpan(Math.floor(value / yearMillis), TimeUnit.Years);
}
static between(start: Date, end: Date): FriendlyTimeSpan {
const diffMillis = end.getTime() - start.getTime();
return FriendlyTimeSpan.fromMillis(diffMillis);
}
static since(date: Date): FriendlyTimeSpan {
return this.between(date, new Date());
}
toLocalizedAgoText(t: TFunction<"global", undefined>): string {
switch (this.unit) {
case TimeUnit.Seconds:
return t("relative_time.less_than_a_minute_ago");
case TimeUnit.Minutes:
return t("relative_time.n_minutes_ago", { count: this.value });
case TimeUnit.Hours:
return t("relative_time.n_hours_ago", { count: this.value });
case TimeUnit.Days:
return t("relative_time.n_days_ago", { count: this.value });
case TimeUnit.Weeks:
return t("relative_time.n_weeks_ago", { count: this.value });
case TimeUnit.Months:
return t("relative_time.n_months_ago", { count: this.value });
case TimeUnit.Years:
return t("relative_time.n_years_ago", { count: this.value });
}
}
}
export function timeAgoI18n({
input,
t,
fuzzy = undefined,
}: {
input: Date | string;
t: TFunction<"global", undefined>;
fuzzy?: FuzzySpecT;
}) {
Iif (input === undefined) return "";
const date = new Date(input);
const diffMillis = Date.now() - date.getTime();
if (fuzzy && diffMillis < fuzzy.millis) {
// if fuzzyMillis and fuzzyText are both set, then for times less than fuzzyMillis, we return fuzzyText
return t(fuzzy.translationKey) as string;
}
return FriendlyTimeSpan.fromMillis(diffMillis).toLocalizedAgoText(t);
}
|