feat: add timezones to timestamp rendering (#36529)

pull/36422/head
Martin Schoeler 6 months ago committed by GitHub
parent 5031e0e179
commit ccff0b3ccf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 10
      packages/message-parser/src/grammar.pegjs
  2. 40
      packages/message-parser/src/utils.ts
  3. 83
      packages/message-parser/tests/timestamp.test.ts

@ -34,6 +34,7 @@
unorderedList,
timestamp,
timestampFromHours,
timestampFromIsoTime,
} = require('./utils');
let skipBold = false;
@ -83,17 +84,18 @@ TimestampType = "t" / "T" / "d" / "D" / "f" / "F" / "R"
Unixtime = d:Digit |10| { return d.join(''); }
TimestampHoursMinutesSeconds = hours:Digit |2| ":" minutes:Digit|2| ":" seconds:Digit |2| "Z"? { return timestampFromHours(hours.join(''), minutes.join(''), seconds.join('')); }
TimestampHoursMinutesSeconds = hours:Digit |2| ":" minutes:Digit|2| ":" seconds:Digit |2| tz:Timezone? { return timestampFromHours(hours.join(''), minutes.join(''), seconds.join(''), tz); }
TimestampHoursMinutes = hours:Digit |2| ":" minutes:Digit|2| "Z"? { return timestampFromHours(hours.join(''), minutes.join('')); }
TimestampHoursMinutes = hours:Digit |2| ":" minutes:Digit|2| tz:Timezone? { return timestampFromHours(hours.join(''), minutes.join(''),undefined, tz); }
Timestamp = TimestampHoursMinutesSeconds / TimestampHoursMinutes
Timezone = offset:('+'/'-') tzHour: Digit |2| ':' tzMinute: Digit |2| { return `${offset}${tzHour.join('')}:${tzMinute.join('')}` }
ISO8601Date = year:Digit |4| "-" month:Digit |2| "-" day:Digit |2| "T" hours:Digit |2| ":" minutes:Digit|2| ":" seconds:Digit |2| "." milliseconds:Digit |3| "Z"? { return new Date(year.join('') + '-' + month.join('') + '-' + day.join('') + 'T' + hours.join('') + ':' + minutes.join('') + ':' + seconds.join('') + '.' + milliseconds.join('') + 'Z').getTime().toString(); }
ISO8601Date = year:Digit |4| "-" month:Digit |2| "-" day:Digit |2| "T" hours:Digit |2| ":" minutes:Digit|2| ":" seconds:Digit |2| "." milliseconds:Digit |3| tz:Timezone? { return timestampFromIsoTime({year: year.join(''), month: month.join(''), day: day.join(''), hours: hours.join(''), minutes: minutes.join(''), seconds: seconds.join(''), milliseconds: milliseconds.join(''), timezone: tz}) }
ISO8601DateWithoutMilliseconds = year:Digit |4| "-" month:Digit |2| "-" day:Digit |2| "T" hours:Digit |2| ":" minutes:Digit|2| ":" seconds:Digit |2| "Z"? { return new Date(year.join('') + '-' + month.join('') + '-' + day.join('') + 'T' + hours.join('') + ':' + minutes.join('') + ':' + seconds.join('') + 'Z').getTime().toString(); }
ISO8601DateWithoutMilliseconds = year:Digit |4| "-" month:Digit |2| "-" day:Digit |2| "T" hours:Digit |2| ":" minutes:Digit|2| ":" seconds:Digit |2| tz:Timezone? { return timestampFromIsoTime({year: year.join(''), month: month.join(''), day: day.join(''), hours: hours.join(''), minutes: minutes.join(''), seconds: seconds.join(''), timezone: tz}) }
TimestampRules = "<t:" date:(Unixtime / ISO8601Date / ISO8601DateWithoutMilliseconds / Timestamp) ":" format:TimestampType ">" { return timestamp(date, format); } / "<t:" date:(Unixtime / ISO8601Date / ISO8601DateWithoutMilliseconds / Timestamp) ">" { return timestamp(date); }

@ -255,14 +255,48 @@ export const timestampFromHours = (
hours: string,
minutes = '00',
seconds = '00',
timezone = '',
) => {
const date = new Date();
const yearMonthDay = date.toISOString().split('T')[0];
return new Date(`${yearMonthDay}T${hours}:${minutes}:${seconds}Z`)
.getTime()
.toString();
const timestamp =
(new Date(
`${yearMonthDay}T${hours}:${minutes}:${seconds}${timezone}`,
).getTime() /
1000) |
0;
return timestamp.toString();
};
export const timestampFromIsoTime = ({
year,
month,
day,
hours,
minutes,
seconds,
milliseconds,
timezone,
}: {
year: string[];
month: string[];
day: string[];
hours: string[];
minutes: string[];
seconds: string[];
milliseconds?: string[];
timezone?: string;
}) => {
const date =
(new Date(
`${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds || '000'}${timezone ? `${timezone}` : ''}`,
).getTime() /
1000) |
0;
return date.toString();
};
export const extractFirstResult = (

@ -35,34 +35,89 @@ test.each([
test.each([
[
'<t:2025-07-22T10:00:00.000Z:R>',
[paragraph([timestamp('1753178400000', 'R')])],
'<t:2025-07-22T10:00:00.000+00:00:R>',
[
paragraph([
timestamp(
(Date.parse('2025-07-22T10:00:00.000+00:00') / 1000).toString(),
'R',
),
]),
],
],
[
'<t:2025-07-22T10:00:00.000Z:R>',
[paragraph([timestamp('1753178400000', 'R')])],
'<t:2025-07-22T10:00:00.000+00:00:R>',
[
paragraph([
timestamp(
(Date.parse('2025-07-22T10:00:00.000+00:00') / 1000).toString(),
'R',
),
]),
],
],
[
'<t:2025-07-22T10:00:00.000:R>',
[paragraph([timestamp('1753178400000', 'R')])],
'<t:2025-07-22T10:00:00.000+00:00:R>',
[
paragraph([
timestamp(
(Date.parse('2025-07-22T10:00:00.000+00:00') / 1000).toString(),
'R',
),
]),
],
],
['<t:2025-07-22T10:00:00:R>', [paragraph([timestamp('1753178400000', 'R')])]],
[
'<t:10:00:00:R>',
[paragraph([timestamp(timestampFromHours('10', '00', '00'), 'R')])],
'<t:2025-07-22T10:00:00+00:00:R>',
[
paragraph([
timestamp(
(Date.parse('2025-07-22T10:00:00+00:00') / 1000).toString(),
'R',
),
]),
],
],
[
'<t:10:00:R>',
[paragraph([timestamp(timestampFromHours('10', '00', '00'), 'R')])],
'<t:10:00:00+00:00:R>',
[
paragraph([
timestamp(timestampFromHours('10', '00', '00', '+00:00'), 'R'),
]),
],
],
[
'<t:10:00:00>',
[paragraph([timestamp(timestampFromHours('10', '00', '00'), 't')])],
'<t:10:00+00:00:R>',
[
paragraph([
timestamp(timestampFromHours('10', '00', '00', '+00:00'), 'R'),
]),
],
],
[
'<t:10:00:05+00:00>',
[
paragraph([
timestamp(timestampFromHours('10', '00', '05', '+00:00'), 't'),
]),
],
],
[
'<t:10:00>',
'<t:10:00+00:00>',
[paragraph([timestamp(timestampFromHours('10', '00', '00'), 't')])],
],
[
'<t:2025-07-24T20:19:58.154+00:00:R>',
[
paragraph([
timestamp(
((Date.parse('2025-07-24T20:19:58.154+00:00') / 1000) | 0).toString(),
'R',
),
]),
],
],
])('parses %p', (input, output) => {
expect(parse(input)).toMatchObject(output);
});

Loading…
Cancel
Save