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 117 118 | 34x 34x 34x 34x 34x 34x 34x 69x 14x 557x 557x 550x 1x 549x 2x 547x 2x 545x 1x 544x 1x 543x 1x 542x 542x 542x 1x 541x 543x 543x 543x 543x 1x 1x 1x 542x | 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;
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(locale: string): string {
const relativeTime = new Intl.RelativeTimeFormat(locale, {
style: "long", // 1 minute ago vs 1 min. ago
numeric: "auto", // yesterday vs 1 day ago
});
switch (this.unit) {
case TimeUnit.Seconds:
return relativeTime.format(-this.value, "second");
case TimeUnit.Minutes:
return relativeTime.format(-this.value, "minute");
case TimeUnit.Hours:
return relativeTime.format(-this.value, "hour");
case TimeUnit.Days:
return relativeTime.format(-this.value, "day");
case TimeUnit.Weeks:
return relativeTime.format(-this.value, "week");
case TimeUnit.Months:
return relativeTime.format(-this.value, "month");
case TimeUnit.Years:
return relativeTime.format(-this.value, "year");
}
}
}
export function timeAgo({
since,
t,
locale,
minimumUnit = TimeUnit.Seconds,
}: {
since: Date;
t: TFunction<"global", undefined>;
locale: string;
minimumUnit?: TimeUnit;
}): string {
const diffMillis = Date.now() - since.getTime();
const timeSpan = FriendlyTimeSpan.fromMillis(diffMillis);
if (minimumUnit && timeSpan.unit < minimumUnit) {
Iif (minimumUnit == TimeUnit.Minutes)
return t("global:relative_time.less_than_a_minute_ago");
if (minimumUnit == TimeUnit.Hours)
return t("global:relative_time.less_than_one_hour_ago");
}
return timeSpan.toLocalizedAgoText(locale);
}
|