signal-desktop/ts/util/timestamp.ts

209 lines
4.5 KiB
TypeScript
Raw Normal View History

2023-01-03 19:55:46 +00:00
// Copyright 2021 Signal Messenger, LLC
// 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';
2023-05-25 17:17:10 +00:00
import { formatTimestamp } from './formatTimestamp';
2022-01-26 23:05:26 +00:00
type RawTimestamp = Readonly<number | Date | Moment>;
2021-09-24 17:01:46 +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);
}
export const isSameDay = (a: RawTimestamp, b: RawTimestamp): boolean =>
2022-01-26 23:05:26 +00:00
moment(a).isSame(b, 'day');
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;
if (diff < HOUR || isToday(timestamp)) {
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-05-25 17:17:10 +00:00
return formatTimestamp(timestamp, { weekday: 'short' });
2022-01-26 23:05:26 +00:00
}
if (m.isSame(now, 'year')) {
2023-05-25 17:17:10 +00:00
return formatTimestamp(timestamp, {
day: 'numeric',
month: 'short',
2023-05-25 17:17:10 +00:00
});
2022-01-26 23:05:26 +00:00
}
2023-05-25 17:17:10 +00:00
return formatTimestamp(timestamp, {
day: 'numeric',
month: 'short',
year: 'numeric',
2023-05-25 17:17:10 +00:00
});
2022-01-26 23:05:26 +00:00
}
export function formatDateTimeForAttachment(
i18n: LocalizerType,
rawTimestamp: RawTimestamp
): string {
const timestamp = rawTimestamp.valueOf();
const now = Date.now();
const diff = now - timestamp;
if (diff < HOUR || isToday(timestamp)) {
return formatTime(i18n, rawTimestamp, now);
}
const m = moment(timestamp);
if (diff < WEEK && m.isSame(now, 'month')) {
2023-05-25 17:17:10 +00:00
return formatTimestamp(timestamp, {
weekday: 'short',
hour: 'numeric',
minute: 'numeric',
2023-05-25 17:17:10 +00:00
});
}
if (m.isSame(now, 'year')) {
2023-05-25 17:17:10 +00:00
return formatTimestamp(timestamp, {
day: 'numeric',
month: 'short',
hour: 'numeric',
minute: 'numeric',
2023-05-25 17:17:10 +00:00
});
}
2023-05-25 17:17:10 +00:00
return formatTimestamp(timestamp, {
day: 'numeric',
month: 'short',
year: 'numeric',
hour: 'numeric',
minute: 'numeric',
2023-05-25 17:17:10 +00:00
});
}
2022-01-26 23:05:26 +00:00
export function formatDateTimeLong(
i18n: LocalizerType,
rawTimestamp: RawTimestamp
): string {
const timestamp = rawTimestamp.valueOf();
2022-01-26 23:05:26 +00:00
if (isToday(rawTimestamp)) {
2023-03-30 00:03:25 +00:00
return i18n('icu:timestampFormat__long--today', {
2023-05-25 17:17:10 +00:00
time: formatTimestamp(timestamp, {
hour: 'numeric',
minute: 'numeric',
2023-05-25 17:17:10 +00:00
}),
2023-03-27 23:37:39 +00:00
});
}
if (isYesterday(rawTimestamp)) {
2023-03-30 00:03:25 +00:00
return i18n('icu:timestampFormat__long--yesterday', {
2023-05-25 17:17:10 +00:00
time: formatTimestamp(timestamp, {
hour: 'numeric',
minute: 'numeric',
2023-05-25 17:17:10 +00:00
}),
2023-03-27 23:37:39 +00:00
});
2022-01-26 23:05:26 +00:00
}
2023-05-25 17:17:10 +00:00
return formatTimestamp(timestamp, {
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
month: 'short',
year: 'numeric',
2023-05-25 17:17:10 +00:00
});
2022-01-26 23:05:26 +00:00
}
export function formatTime(
i18n: LocalizerType,
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();
const diff = now.valueOf() - timestamp;
2022-01-26 23:05:26 +00:00
if (diff < MINUTE) {
2023-03-30 00:03:25 +00:00
return i18n('icu:justNow');
2022-01-26 23:05:26 +00:00
}
if (diff < HOUR) {
2023-03-30 00:03:25 +00:00
return i18n('icu:minutesAgo', {
2023-04-03 19:03:00 +00:00
minutes: Math.floor(diff / MINUTE),
2023-03-27 23:37:39 +00:00
});
2022-01-26 23:05:26 +00:00
}
2022-05-06 19:02:44 +00:00
if (isRelativeTime) {
2023-03-30 00:03:25 +00:00
return i18n('icu:hoursAgo', {
2023-04-03 19:03:00 +00:00
hours: Math.floor(diff / HOUR),
2023-03-27 23:37:39 +00:00
});
2022-05-06 19:02:44 +00:00
}
return formatTimestamp(timestamp, {
hour: 'numeric',
minute: '2-digit',
});
2022-01-26 23:05:26 +00:00
}
export function formatDate(
i18n: LocalizerType,
rawTimestamp: RawTimestamp
): string {
if (isToday(rawTimestamp)) {
2023-03-30 00:03:25 +00:00
return i18n('icu:today');
2022-01-26 23:05:26 +00:00
}
if (isYesterday(rawTimestamp)) {
2023-03-30 00:03:25 +00:00
return i18n('icu:yesterday');
2022-01-26 23:05:26 +00:00
}
const m = moment(rawTimestamp);
const timestamp = rawTimestamp.valueOf();
if (Math.abs(m.diff(Date.now())) < 6 * MONTH) {
2023-05-25 17:17:10 +00:00
return formatTimestamp(timestamp, {
day: 'numeric',
month: 'short',
weekday: 'short',
2023-05-25 17:17:10 +00:00
});
}
2022-01-26 23:05:26 +00:00
2023-05-25 17:17:10 +00:00
return formatTimestamp(timestamp, {
day: 'numeric',
month: 'short',
year: 'numeric',
2023-05-25 17:17:10 +00:00
});
2021-09-24 17:01:46 +00:00
}