2023-01-03 19:55:46 +00:00
|
|
|
// Copyright 2021 Signal Messenger, LLC
|
2021-03-22 21:08:52 +00:00
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2022-01-26 23:05:26 +00:00
|
|
|
import type { Moment } from 'moment';
|
|
|
|
import moment from 'moment';
|
|
|
|
import type { LocalizerType } from '../types/Util';
|
|
|
|
import { DAY, HOUR, MINUTE, MONTH, WEEK } from './durations';
|
|
|
|
|
|
|
|
type RawTimestamp = Readonly<number | Date | Moment>;
|
2021-09-24 17:01:46 +00:00
|
|
|
|
2021-03-22 21:08:52 +00:00
|
|
|
export function isMoreRecentThan(timestamp: number, delta: number): boolean {
|
|
|
|
return timestamp > Date.now() - delta;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isOlderThan(timestamp: number, delta: number): boolean {
|
|
|
|
return timestamp <= Date.now() - delta;
|
|
|
|
}
|
2021-08-23 22:45:11 +00:00
|
|
|
|
|
|
|
export function isInPast(timestamp: number): boolean {
|
|
|
|
return isOlderThan(timestamp, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isInFuture(timestamp: number): boolean {
|
|
|
|
return isMoreRecentThan(timestamp, 0);
|
|
|
|
}
|
2021-09-24 17:01:46 +00:00
|
|
|
|
|
|
|
export function toDayMillis(timestamp: number): number {
|
2022-01-26 23:05:26 +00:00
|
|
|
return timestamp - (timestamp % DAY);
|
|
|
|
}
|
|
|
|
|
2022-02-02 18:27:44 +00:00
|
|
|
export const isSameDay = (a: RawTimestamp, b: RawTimestamp): boolean =>
|
2022-01-26 23:05:26 +00:00
|
|
|
moment(a).isSame(b, 'day');
|
|
|
|
|
2022-02-02 18:27:44 +00:00
|
|
|
export const isToday = (rawTimestamp: RawTimestamp): boolean =>
|
2022-01-26 23:05:26 +00:00
|
|
|
isSameDay(rawTimestamp, Date.now());
|
|
|
|
|
|
|
|
const isYesterday = (rawTimestamp: RawTimestamp): boolean =>
|
|
|
|
isSameDay(rawTimestamp, moment().subtract(1, 'day'));
|
|
|
|
|
|
|
|
export function formatDateTimeShort(
|
|
|
|
i18n: LocalizerType,
|
|
|
|
rawTimestamp: RawTimestamp
|
|
|
|
): string {
|
|
|
|
const timestamp = rawTimestamp.valueOf();
|
|
|
|
|
|
|
|
const now = Date.now();
|
|
|
|
const diff = now - timestamp;
|
|
|
|
|
2023-03-02 18:43:25 +00:00
|
|
|
const locale = window.getPreferredSystemLocales();
|
|
|
|
|
2022-02-23 18:15:15 +00:00
|
|
|
if (diff < HOUR || isToday(timestamp)) {
|
2022-03-03 20:23:10 +00:00
|
|
|
return formatTime(i18n, rawTimestamp, now);
|
2022-01-26 23:05:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const m = moment(timestamp);
|
|
|
|
|
|
|
|
if (diff < WEEK && m.isSame(now, 'month')) {
|
2023-03-02 18:43:25 +00:00
|
|
|
return new Intl.DateTimeFormat(locale, { weekday: 'short' }).format(
|
|
|
|
timestamp
|
|
|
|
);
|
2022-01-26 23:05:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (m.isSame(now, 'year')) {
|
2023-03-02 18:43:25 +00:00
|
|
|
return new Intl.DateTimeFormat(locale, {
|
|
|
|
day: 'numeric',
|
|
|
|
month: 'short',
|
|
|
|
}).format(timestamp);
|
2022-01-26 23:05:26 +00:00
|
|
|
}
|
|
|
|
|
2023-03-02 18:43:25 +00:00
|
|
|
return new Intl.DateTimeFormat(locale, {
|
|
|
|
day: 'numeric',
|
|
|
|
month: 'short',
|
|
|
|
year: 'numeric',
|
|
|
|
}).format(timestamp);
|
2022-01-26 23:05:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function formatDateTimeLong(
|
|
|
|
i18n: LocalizerType,
|
|
|
|
rawTimestamp: RawTimestamp
|
|
|
|
): string {
|
2023-03-02 18:43:25 +00:00
|
|
|
const locale = window.getPreferredSystemLocales();
|
|
|
|
const timestamp = rawTimestamp.valueOf();
|
|
|
|
|
2022-01-26 23:05:26 +00:00
|
|
|
if (isToday(rawTimestamp)) {
|
2023-03-02 18:43:25 +00:00
|
|
|
return i18n('timestampFormat__long--today', [
|
|
|
|
new Intl.DateTimeFormat(locale, {
|
|
|
|
hour: 'numeric',
|
|
|
|
minute: 'numeric',
|
|
|
|
}).format(timestamp),
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isYesterday(rawTimestamp)) {
|
|
|
|
return i18n('timestampFormat__long--yesterday', [
|
|
|
|
new Intl.DateTimeFormat(locale, {
|
|
|
|
hour: 'numeric',
|
|
|
|
minute: 'numeric',
|
|
|
|
}).format(timestamp),
|
|
|
|
]);
|
2022-01-26 23:05:26 +00:00
|
|
|
}
|
|
|
|
|
2023-03-02 18:43:25 +00:00
|
|
|
return new Intl.DateTimeFormat(locale, {
|
|
|
|
day: 'numeric',
|
|
|
|
hour: 'numeric',
|
|
|
|
minute: 'numeric',
|
|
|
|
month: 'short',
|
|
|
|
year: 'numeric',
|
|
|
|
}).format(timestamp);
|
2022-01-26 23:05:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function formatTime(
|
|
|
|
i18n: LocalizerType,
|
2022-03-03 20:23:10 +00:00
|
|
|
rawTimestamp: RawTimestamp,
|
2022-05-06 19:02:44 +00:00
|
|
|
now: RawTimestamp,
|
|
|
|
isRelativeTime?: boolean
|
2022-01-26 23:05:26 +00:00
|
|
|
): string {
|
|
|
|
const timestamp = rawTimestamp.valueOf();
|
2022-03-03 20:23:10 +00:00
|
|
|
const diff = now.valueOf() - timestamp;
|
2022-01-26 23:05:26 +00:00
|
|
|
|
|
|
|
if (diff < MINUTE) {
|
|
|
|
return i18n('justNow');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (diff < HOUR) {
|
|
|
|
return i18n('minutesAgo', [Math.floor(diff / MINUTE).toString()]);
|
|
|
|
}
|
|
|
|
|
2022-05-06 19:02:44 +00:00
|
|
|
if (isRelativeTime) {
|
|
|
|
return i18n('hoursAgo', [Math.floor(diff / HOUR).toString()]);
|
|
|
|
}
|
|
|
|
|
2022-02-23 18:15:15 +00:00
|
|
|
return new Date(timestamp).toLocaleTimeString([], {
|
|
|
|
hour: 'numeric',
|
|
|
|
minute: '2-digit',
|
|
|
|
});
|
2022-01-26 23:05:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function formatDate(
|
|
|
|
i18n: LocalizerType,
|
|
|
|
rawTimestamp: RawTimestamp
|
|
|
|
): string {
|
|
|
|
if (isToday(rawTimestamp)) {
|
|
|
|
return i18n('today');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isYesterday(rawTimestamp)) {
|
|
|
|
return i18n('yesterday');
|
|
|
|
}
|
|
|
|
|
2023-03-02 18:43:25 +00:00
|
|
|
const locale = window.getPreferredSystemLocales();
|
2022-01-26 23:05:26 +00:00
|
|
|
const m = moment(rawTimestamp);
|
|
|
|
|
2023-03-02 18:43:25 +00:00
|
|
|
const timestamp = rawTimestamp.valueOf();
|
|
|
|
|
|
|
|
if (Math.abs(m.diff(Date.now())) < 6 * MONTH) {
|
|
|
|
return new Intl.DateTimeFormat(locale, {
|
|
|
|
day: 'numeric',
|
|
|
|
month: 'short',
|
|
|
|
weekday: 'short',
|
|
|
|
}).format(timestamp);
|
|
|
|
}
|
2022-01-26 23:05:26 +00:00
|
|
|
|
2023-03-02 18:43:25 +00:00
|
|
|
return new Intl.DateTimeFormat(locale, {
|
|
|
|
day: 'numeric',
|
|
|
|
month: 'short',
|
|
|
|
year: 'numeric',
|
|
|
|
}).format(timestamp);
|
2021-09-24 17:01:46 +00:00
|
|
|
}
|