Fix RangeError invalid timestamp
This commit is contained in:
parent
35c3349fe6
commit
e2f39ed5fa
2 changed files with 39 additions and 29 deletions
17
ts/util/formatTimestamp.ts
Normal file
17
ts/util/formatTimestamp.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2023 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { assertDev } from './assert';
|
||||||
|
|
||||||
|
export function formatTimestamp(
|
||||||
|
timestamp: number,
|
||||||
|
options: Intl.DateTimeFormatOptions
|
||||||
|
): string {
|
||||||
|
const locale = window.getPreferredSystemLocales();
|
||||||
|
try {
|
||||||
|
return new Intl.DateTimeFormat(locale, options).format(timestamp);
|
||||||
|
} catch (err) {
|
||||||
|
assertDev(false, 'invalid timestamp');
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import type { Moment } from 'moment';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import type { LocalizerType } from '../types/Util';
|
import type { LocalizerType } from '../types/Util';
|
||||||
import { DAY, HOUR, MINUTE, MONTH, WEEK } from './durations';
|
import { DAY, HOUR, MINUTE, MONTH, WEEK } from './durations';
|
||||||
|
import { formatTimestamp } from './formatTimestamp';
|
||||||
|
|
||||||
type RawTimestamp = Readonly<number | Date | Moment>;
|
type RawTimestamp = Readonly<number | Date | Moment>;
|
||||||
|
|
||||||
|
@ -46,8 +47,6 @@ export function formatDateTimeShort(
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const diff = now - timestamp;
|
const diff = now - timestamp;
|
||||||
|
|
||||||
const locale = window.getPreferredSystemLocales();
|
|
||||||
|
|
||||||
if (diff < HOUR || isToday(timestamp)) {
|
if (diff < HOUR || isToday(timestamp)) {
|
||||||
return formatTime(i18n, rawTimestamp, now);
|
return formatTime(i18n, rawTimestamp, now);
|
||||||
}
|
}
|
||||||
|
@ -55,23 +54,21 @@ export function formatDateTimeShort(
|
||||||
const m = moment(timestamp);
|
const m = moment(timestamp);
|
||||||
|
|
||||||
if (diff < WEEK && m.isSame(now, 'month')) {
|
if (diff < WEEK && m.isSame(now, 'month')) {
|
||||||
return new Intl.DateTimeFormat(locale, { weekday: 'short' }).format(
|
return formatTimestamp(timestamp, { weekday: 'short' });
|
||||||
timestamp
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m.isSame(now, 'year')) {
|
if (m.isSame(now, 'year')) {
|
||||||
return new Intl.DateTimeFormat(locale, {
|
return formatTimestamp(timestamp, {
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
month: 'short',
|
month: 'short',
|
||||||
}).format(timestamp);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Intl.DateTimeFormat(locale, {
|
return formatTimestamp(timestamp, {
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
month: 'short',
|
month: 'short',
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
}).format(timestamp);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatDateTimeForAttachment(
|
export function formatDateTimeForAttachment(
|
||||||
|
@ -83,8 +80,6 @@ export function formatDateTimeForAttachment(
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const diff = now - timestamp;
|
const diff = now - timestamp;
|
||||||
|
|
||||||
const locale = window.getPreferredSystemLocales();
|
|
||||||
|
|
||||||
if (diff < HOUR || isToday(timestamp)) {
|
if (diff < HOUR || isToday(timestamp)) {
|
||||||
return formatTime(i18n, rawTimestamp, now);
|
return formatTime(i18n, rawTimestamp, now);
|
||||||
}
|
}
|
||||||
|
@ -92,63 +87,62 @@ export function formatDateTimeForAttachment(
|
||||||
const m = moment(timestamp);
|
const m = moment(timestamp);
|
||||||
|
|
||||||
if (diff < WEEK && m.isSame(now, 'month')) {
|
if (diff < WEEK && m.isSame(now, 'month')) {
|
||||||
return new Intl.DateTimeFormat(locale, {
|
return formatTimestamp(timestamp, {
|
||||||
weekday: 'short',
|
weekday: 'short',
|
||||||
hour: 'numeric',
|
hour: 'numeric',
|
||||||
minute: 'numeric',
|
minute: 'numeric',
|
||||||
}).format(timestamp);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m.isSame(now, 'year')) {
|
if (m.isSame(now, 'year')) {
|
||||||
return new Intl.DateTimeFormat(locale, {
|
return formatTimestamp(timestamp, {
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
month: 'short',
|
month: 'short',
|
||||||
hour: 'numeric',
|
hour: 'numeric',
|
||||||
minute: 'numeric',
|
minute: 'numeric',
|
||||||
}).format(timestamp);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Intl.DateTimeFormat(locale, {
|
return formatTimestamp(timestamp, {
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
month: 'short',
|
month: 'short',
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
hour: 'numeric',
|
hour: 'numeric',
|
||||||
minute: 'numeric',
|
minute: 'numeric',
|
||||||
}).format(timestamp);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatDateTimeLong(
|
export function formatDateTimeLong(
|
||||||
i18n: LocalizerType,
|
i18n: LocalizerType,
|
||||||
rawTimestamp: RawTimestamp
|
rawTimestamp: RawTimestamp
|
||||||
): string {
|
): string {
|
||||||
const locale = window.getPreferredSystemLocales();
|
|
||||||
const timestamp = rawTimestamp.valueOf();
|
const timestamp = rawTimestamp.valueOf();
|
||||||
|
|
||||||
if (isToday(rawTimestamp)) {
|
if (isToday(rawTimestamp)) {
|
||||||
return i18n('icu:timestampFormat__long--today', {
|
return i18n('icu:timestampFormat__long--today', {
|
||||||
time: new Intl.DateTimeFormat(locale, {
|
time: formatTimestamp(timestamp, {
|
||||||
hour: 'numeric',
|
hour: 'numeric',
|
||||||
minute: 'numeric',
|
minute: 'numeric',
|
||||||
}).format(timestamp),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isYesterday(rawTimestamp)) {
|
if (isYesterday(rawTimestamp)) {
|
||||||
return i18n('icu:timestampFormat__long--yesterday', {
|
return i18n('icu:timestampFormat__long--yesterday', {
|
||||||
time: new Intl.DateTimeFormat(locale, {
|
time: formatTimestamp(timestamp, {
|
||||||
hour: 'numeric',
|
hour: 'numeric',
|
||||||
minute: 'numeric',
|
minute: 'numeric',
|
||||||
}).format(timestamp),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Intl.DateTimeFormat(locale, {
|
return formatTimestamp(timestamp, {
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
hour: 'numeric',
|
hour: 'numeric',
|
||||||
minute: 'numeric',
|
minute: 'numeric',
|
||||||
month: 'short',
|
month: 'short',
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
}).format(timestamp);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatTime(
|
export function formatTime(
|
||||||
|
@ -194,22 +188,21 @@ export function formatDate(
|
||||||
return i18n('icu:yesterday');
|
return i18n('icu:yesterday');
|
||||||
}
|
}
|
||||||
|
|
||||||
const locale = window.getPreferredSystemLocales();
|
|
||||||
const m = moment(rawTimestamp);
|
const m = moment(rawTimestamp);
|
||||||
|
|
||||||
const timestamp = rawTimestamp.valueOf();
|
const timestamp = rawTimestamp.valueOf();
|
||||||
|
|
||||||
if (Math.abs(m.diff(Date.now())) < 6 * MONTH) {
|
if (Math.abs(m.diff(Date.now())) < 6 * MONTH) {
|
||||||
return new Intl.DateTimeFormat(locale, {
|
return formatTimestamp(timestamp, {
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
month: 'short',
|
month: 'short',
|
||||||
weekday: 'short',
|
weekday: 'short',
|
||||||
}).format(timestamp);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Intl.DateTimeFormat(locale, {
|
return formatTimestamp(timestamp, {
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
month: 'short',
|
month: 'short',
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
}).format(timestamp);
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue