blob: b7f157fd934798026e2545b548683bacdebc6119 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {LitElement, html} from 'lit-element';
import {standardTime, relativeTime} from './chops-timestamp-helpers.js';
/**
* `<chops-timestamp>`
*
* This element shows a time in a human readable form.
*
* @customElement
*/
export class ChopsTimestamp extends LitElement {
/** @override */
render() {
return html`
${this._displayedTime}
`;
}
/** @override */
static get properties() {
return {
/** The data for the time which can be in any format readable by
* Date.parse.
*/
timestamp: {type: String},
/** When true, a shorter version of the date will be displayed. */
short: {type: Boolean},
/**
* The Date object, which is stored in UTC, to be converted to a string.
*/
_date: {type: Object},
};
}
/**
* @return {string} Human-readable timestamp.
*/
get _displayedTime() {
const date = this._date;
const short = this.short;
// TODO(zhangtiff): Add logic to dynamically re-compute relative time
// based on set intervals.
if (!date) return;
if (short) {
return relativeTime(date);
}
return standardTime(date);
}
/** @override */
update(changedProperties) {
if (changedProperties.has('timestamp')) {
this._date = this._parseTimestamp(this.timestamp);
this.setAttribute('title', standardTime(this._date));
}
super.update(changedProperties);
}
/**
* Turns a timestamp string into a native JavaScript Date Object.
* @param {string} timestamp Timestamp string in either an ISO format or
* Unix timestamp format. If Unix time, the function expects the time in
* seconds, not milliseconds.
* @return {Date}
*/
_parseTimestamp(timestamp) {
if (!timestamp) return;
let unixTimeMs = 0;
// Make sure to do Date.parse before Number.parseInt because parseInt
// will parse numbers within a string.
if (/^\d+$/.test(timestamp)) {
// Check if a string contains only digits before guessing it's
// unix time. This is necessary because Number.parseInt will parse
// number strings that contain non-numbers.
unixTimeMs = Number.parseInt(timestamp) * 1000;
} else {
// Date.parse will parse strings with only numbers as though those
// strings were truncated ISO formatted strings.
unixTimeMs = Date.parse(timestamp);
if (Number.isNaN(unixTimeMs)) {
throw new Error('Timestamp is in an invalid format.');
}
}
return new Date(unixTimeMs);
}
}
customElements.define('chops-timestamp', ChopsTimestamp);