blob: b7f157fd934798026e2545b548683bacdebc6119 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import {LitElement, html} from 'lit-element';
6
7import {standardTime, relativeTime} from './chops-timestamp-helpers.js';
8
9/**
10 * `<chops-timestamp>`
11 *
12 * This element shows a time in a human readable form.
13 *
14 * @customElement
15 */
16export class ChopsTimestamp extends LitElement {
17 /** @override */
18 render() {
19 return html`
20 ${this._displayedTime}
21 `;
22 }
23
24 /** @override */
25 static get properties() {
26 return {
27 /** The data for the time which can be in any format readable by
28 * Date.parse.
29 */
30 timestamp: {type: String},
31 /** When true, a shorter version of the date will be displayed. */
32 short: {type: Boolean},
33 /**
34 * The Date object, which is stored in UTC, to be converted to a string.
35 */
36 _date: {type: Object},
37 };
38 }
39
40 /**
41 * @return {string} Human-readable timestamp.
42 */
43 get _displayedTime() {
44 const date = this._date;
45 const short = this.short;
46 // TODO(zhangtiff): Add logic to dynamically re-compute relative time
47 // based on set intervals.
48 if (!date) return;
49 if (short) {
50 return relativeTime(date);
51 }
52 return standardTime(date);
53 }
54
55 /** @override */
56 update(changedProperties) {
57 if (changedProperties.has('timestamp')) {
58 this._date = this._parseTimestamp(this.timestamp);
59 this.setAttribute('title', standardTime(this._date));
60 }
61 super.update(changedProperties);
62 }
63
64 /**
65 * Turns a timestamp string into a native JavaScript Date Object.
66 * @param {string} timestamp Timestamp string in either an ISO format or
67 * Unix timestamp format. If Unix time, the function expects the time in
68 * seconds, not milliseconds.
69 * @return {Date}
70 */
71 _parseTimestamp(timestamp) {
72 if (!timestamp) return;
73
74 let unixTimeMs = 0;
75 // Make sure to do Date.parse before Number.parseInt because parseInt
76 // will parse numbers within a string.
77 if (/^\d+$/.test(timestamp)) {
78 // Check if a string contains only digits before guessing it's
79 // unix time. This is necessary because Number.parseInt will parse
80 // number strings that contain non-numbers.
81 unixTimeMs = Number.parseInt(timestamp) * 1000;
82 } else {
83 // Date.parse will parse strings with only numbers as though those
84 // strings were truncated ISO formatted strings.
85 unixTimeMs = Date.parse(timestamp);
86 if (Number.isNaN(unixTimeMs)) {
87 throw new Error('Timestamp is in an invalid format.');
88 }
89 }
90 return new Date(unixTimeMs);
91 }
92}
93customElements.define('chops-timestamp', ChopsTimestamp);