Skip to content

Commit 881c8a5

Browse files
authored
refactor(timestamp): use Intl.RelativeTimeFormatUnit (#2504)
1 parent 6cb9318 commit 881c8a5

File tree

4 files changed

+52
-21
lines changed

4 files changed

+52
-21
lines changed

.changeset/short-tools-lay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@patternfly/elements": minor
3+
---
4+
5+
`<pf-timestamp>`: improved performance by using browser-standard features to calculate relative time

elements/pf-timestamp/demo/pf-timestamp.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ <h3>Custom format</h3>
2929
</script>
3030
</section>
3131

32+
<section>
33+
<h3>Relative formats</h3>
34+
<p><pf-timestamp date="Tue Aug 09 2006 14:57:00 GMT-0400 (Eastern Daylight Time)" relative></pf-timestamp></p>
35+
<p><pf-timestamp date="Tue Aug 09 2006 14:57:00 GMT-0400 (Eastern Daylight Time)" locale="es" relative></pf-timestamp></p>
36+
<p><pf-timestamp date="Tue Aug 09 2022 14:57:00 GMT-0400 (Eastern Daylight Time)" relative></pf-timestamp></p>
37+
<p><pf-timestamp date="Tue Aug 09 2022 14:57:00 GMT-0400 (Eastern Daylight Time)" locale="es" relative></pf-timestamp></p>
38+
<p><pf-timestamp date="Tue Aug 09 2099 14:57:00 GMT-0400 (Eastern Daylight Time)" relative></pf-timestamp></p>
39+
<p><pf-timestamp date="Tue Aug 09 2099 14:57:00 GMT-0400 (Eastern Daylight Time)" locale="es" relative></pf-timestamp></p>
40+
</section>
41+
3242
<section>
3343
<h3>Default tooltip</h3>
3444
<p>

elements/pf-timestamp/pf-timestamp.ts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -78,40 +78,38 @@ export class PfTimestamp extends LitElement {
7878
* https://github.com/github/time-elements/blob/master/src/relative-time.js
7979
*/
8080
#getTimeRelative(date: Date) {
81+
const rtf = new Intl.RelativeTimeFormat(this.locale, { localeMatcher: 'best fit', numeric: 'auto', style: 'long' });
8182
const ms: number = date.getTime() - Date.now();
82-
const tense = ms > 0 ? 'until' : 'ago';
83-
let str = 'just now';
83+
const tense = ms > 0 ? 1 : -1;
84+
let qty = 0;
85+
let units: Intl.RelativeTimeFormatUnit | undefined;
8486
const s = Math.round(Math.abs(ms) / 1000);
8587
const min = Math.round(s / 60);
8688
const h = Math.round(min / 60);
8789
const d = Math.round(h / 24);
8890
const m = Math.round(d / 30);
8991
const y = Math.round(m / 12);
90-
if (m >= 18) {
91-
str = `${y} years`;
92-
} else if (m >= 12) {
93-
str = 'a year';
94-
} else if (d >= 45) {
95-
str = `${m} months`;
92+
if (m >= 12) {
93+
qty = y;
94+
units = 'year';
9695
} else if (d >= 30) {
97-
str = 'a month';
98-
} else if (h >= 36) {
99-
str = `${d} days`;
96+
qty = m;
97+
units = 'month';
10098
} else if (h >= 24) {
101-
str = 'a day';
102-
} else if (min >= 90) {
103-
str = `${h} hours`;
99+
qty = d;
100+
units = 'day';
104101
} else if (min >= 45) {
105-
str = 'an hour';
106-
} else if (s >= 90) {
107-
str = `${min} minutes`;
102+
qty = h;
103+
units = 'hour';
108104
} else if (s >= 45) {
109-
str = 'a minute';
105+
qty = min;
106+
units = 'minute';
110107
} else if (s >= 10) {
111-
str = `${s} seconds`;
108+
qty = s;
109+
units = 'second';
112110
}
113111

114-
return str !== 'just now' ? `${str} ${tense}` : str;
112+
return typeof (units) !== 'undefined' ? rtf.format(tense * qty, units) : 'just now';
115113
}
116114
}
117115

elements/pf-timestamp/test/pf-timestamp.spec.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,30 @@ describe('<pf-timestamp>', function() {
158158
expect(element.time).to.equal(expected);
159159
});
160160

161-
it('should show relative time', async function() {
161+
it('should show relative time of the moment', async function() {
162+
const date = new Date();
163+
const element = await createFixture<PfTimestamp>(html`
164+
<pf-timestamp date="${date.toString()}" relative></pf-timestamp>
165+
`);
166+
167+
expect(element.time).to.match(/just now/);
168+
});
169+
170+
it('should show relative time in the past', async function() {
162171
const date = new Date(2015, 7, 9, 14, 57, 0);
163172
const element = await createFixture<PfTimestamp>(html`
164173
<pf-timestamp date="${date.toString()}" relative></pf-timestamp>
165174
`);
166175

167176
expect(element.time).to.match(/\d+ years ago/);
168177
});
178+
179+
it('should show relative time in the future', async function() {
180+
const date = new Date(2099, 7, 9, 14, 57, 0);
181+
const element = await createFixture<PfTimestamp>(html`
182+
<pf-timestamp date="${date.toString()}" relative></pf-timestamp>
183+
`);
184+
185+
expect(element.time).to.match(/in \d+ years/);
186+
});
169187
});

0 commit comments

Comments
 (0)