From c977f22047825c0910b806127ae5b59d674bf36d Mon Sep 17 00:00:00 2001 From: Ruslan Sayfutdinov Date: Thu, 6 Feb 2020 18:38:38 +0000 Subject: [PATCH] Show seconds in the UI (#4765) --- src/common/datetime/check_options_support.ts | 31 ++++++++++++++++ src/common/datetime/format_date.ts | 15 ++------ src/common/datetime/format_date_time.ts | 35 ++++++++++++------- src/common/datetime/format_time.ts | 22 ++++++------ src/common/entity/compute_state_display.ts | 6 ++-- src/components/entity/ha-chart-base.js | 2 +- src/components/state-history-chart-line.js | 4 +-- .../state-history-chart-timeline.js | 6 ++-- .../more-info/controls/more-info-sun.ts | 2 +- .../config/automation/ha-automation-picker.ts | 4 +-- .../config/cloud/account/cloud-account.js | 2 +- .../dialog-cloud-certificate.ts | 4 +-- .../event/event-subscribe-card.ts | 4 +-- .../developer-tools/logs/system-log-card.ts | 8 ++--- .../mqtt/mqtt-subscribe-card.ts | 4 +-- src/panels/history/ha-panel-history.js | 2 +- src/panels/logbook/ha-logbook.ts | 8 ++--- src/panels/logbook/ha-panel-logbook.js | 2 +- .../components/hui-timestamp-display.ts | 12 +++---- src/panels/mailbox/ha-panel-mailbox.js | 2 +- .../ha-long-lived-access-tokens-card.js | 2 +- src/panels/profile/ha-refresh-tokens-card.js | 2 +- test-mocha/common/datetime/format_date.ts | 2 +- .../common/datetime/format_date_time.ts | 18 ++++++++-- test-mocha/common/datetime/format_time.ts | 13 ++++++- 25 files changed, 135 insertions(+), 77 deletions(-) create mode 100644 src/common/datetime/check_options_support.ts diff --git a/src/common/datetime/check_options_support.ts b/src/common/datetime/check_options_support.ts new file mode 100644 index 0000000000..614f7f9828 --- /dev/null +++ b/src/common/datetime/check_options_support.ts @@ -0,0 +1,31 @@ +// Check for support of native locale string options +function checkToLocaleDateStringSupportsOptions() { + try { + new Date().toLocaleDateString("i"); + } catch (e) { + return e.name === "RangeError"; + } + return false; +} + +function checkToLocaleTimeStringSupportsOptions() { + try { + new Date().toLocaleTimeString("i"); + } catch (e) { + return e.name === "RangeError"; + } + return false; +} + +function checkToLocaleStringSupportsOptions() { + try { + new Date().toLocaleString("i"); + } catch (e) { + return e.name === "RangeError"; + } + return false; +} + +export const toLocaleDateStringSupportsOptions = checkToLocaleDateStringSupportsOptions(); +export const toLocaleTimeStringSupportsOptions = checkToLocaleTimeStringSupportsOptions(); +export const toLocaleStringSupportsOptions = checkToLocaleStringSupportsOptions(); diff --git a/src/common/datetime/format_date.ts b/src/common/datetime/format_date.ts index 813500ff4a..6a5e7e67f0 100644 --- a/src/common/datetime/format_date.ts +++ b/src/common/datetime/format_date.ts @@ -1,20 +1,11 @@ import fecha from "fecha"; +import { toLocaleDateStringSupportsOptions } from "./check_options_support"; -// Check for support of native locale string options -function toLocaleDateStringSupportsOptions() { - try { - new Date().toLocaleDateString("i"); - } catch (e) { - return e.name === "RangeError"; - } - return false; -} - -export default toLocaleDateStringSupportsOptions() +export const formatDate = toLocaleDateStringSupportsOptions ? (dateObj: Date, locales: string) => dateObj.toLocaleDateString(locales, { year: "numeric", month: "long", day: "numeric", }) - : (dateObj: Date) => fecha.format(dateObj, "mediumDate"); + : (dateObj: Date) => fecha.format(dateObj, "longDate"); diff --git a/src/common/datetime/format_date_time.ts b/src/common/datetime/format_date_time.ts index e8a02139d2..ee6d04f7dd 100644 --- a/src/common/datetime/format_date_time.ts +++ b/src/common/datetime/format_date_time.ts @@ -1,16 +1,7 @@ import fecha from "fecha"; +import { toLocaleStringSupportsOptions } from "./check_options_support"; -// Check for support of native locale string options -function toLocaleStringSupportsOptions() { - try { - new Date().toLocaleString("i"); - } catch (e) { - return e.name === "RangeError"; - } - return false; -} - -export default toLocaleStringSupportsOptions() +export const formatDateTime = toLocaleStringSupportsOptions ? (dateObj: Date, locales: string) => dateObj.toLocaleString(locales, { year: "numeric", @@ -19,4 +10,24 @@ export default toLocaleStringSupportsOptions() hour: "numeric", minute: "2-digit", }) - : (dateObj: Date) => fecha.format(dateObj, "haDateTime"); + : (dateObj: Date) => + fecha.format( + dateObj, + `${fecha.masks.longDate}, ${fecha.masks.shortTime}` + ); + +export const formatDateTimeWithSeconds = toLocaleStringSupportsOptions + ? (dateObj: Date, locales: string) => + dateObj.toLocaleString(locales, { + year: "numeric", + month: "long", + day: "numeric", + hour: "numeric", + minute: "2-digit", + second: "2-digit", + }) + : (dateObj: Date) => + fecha.format( + dateObj, + `${fecha.masks.longDate}, ${fecha.masks.mediumTime}` + ); diff --git a/src/common/datetime/format_time.ts b/src/common/datetime/format_time.ts index 2b747723a7..d8f0c8a8a0 100644 --- a/src/common/datetime/format_time.ts +++ b/src/common/datetime/format_time.ts @@ -1,19 +1,19 @@ import fecha from "fecha"; +import { toLocaleTimeStringSupportsOptions } from "./check_options_support"; -// Check for support of native locale string options -function toLocaleTimeStringSupportsOptions() { - try { - new Date().toLocaleTimeString("i"); - } catch (e) { - return e.name === "RangeError"; - } - return false; -} - -export default toLocaleTimeStringSupportsOptions() +export const formatTime = toLocaleTimeStringSupportsOptions ? (dateObj: Date, locales: string) => dateObj.toLocaleTimeString(locales, { hour: "numeric", minute: "2-digit", }) : (dateObj: Date) => fecha.format(dateObj, "shortTime"); + +export const formatTimeWithSeconds = toLocaleTimeStringSupportsOptions + ? (dateObj: Date, locales: string) => + dateObj.toLocaleTimeString(locales, { + hour: "numeric", + minute: "2-digit", + second: "2-digit", + }) + : (dateObj: Date) => fecha.format(dateObj, "mediumTime"); diff --git a/src/common/entity/compute_state_display.ts b/src/common/entity/compute_state_display.ts index 62304f74e0..c802c7c56a 100644 --- a/src/common/entity/compute_state_display.ts +++ b/src/common/entity/compute_state_display.ts @@ -1,8 +1,8 @@ import { HassEntity } from "home-assistant-js-websocket"; import { computeStateDomain } from "./compute_state_domain"; -import formatDateTime from "../datetime/format_date_time"; -import formatDate from "../datetime/format_date"; -import formatTime from "../datetime/format_time"; +import { formatDateTime } from "../datetime/format_date_time"; +import { formatDate } from "../datetime/format_date"; +import { formatTime } from "../datetime/format_time"; import { LocalizeFunc } from "../translations/localize"; export const computeStateDisplay = ( diff --git a/src/components/entity/ha-chart-base.js b/src/components/entity/ha-chart-base.js index 37eea60bea..ffa76a1d56 100644 --- a/src/components/entity/ha-chart-base.js +++ b/src/components/entity/ha-chart-base.js @@ -6,7 +6,7 @@ import { Debouncer } from "@polymer/polymer/lib/utils/debounce"; import { timeOut } from "@polymer/polymer/lib/utils/async"; import { mixinBehaviors } from "@polymer/polymer/lib/legacy/class"; -import formatTime from "../../common/datetime/format_time"; +import { formatTime } from "../../common/datetime/format_time"; // eslint-disable-next-line no-unused-vars /* global Chart moment Color */ diff --git a/src/components/state-history-chart-line.js b/src/components/state-history-chart-line.js index 6100e4022c..4456b285cc 100644 --- a/src/components/state-history-chart-line.js +++ b/src/components/state-history-chart-line.js @@ -5,7 +5,7 @@ import { PolymerElement } from "@polymer/polymer/polymer-element"; import "./entity/ha-chart-base"; import LocalizeMixin from "../mixins/localize-mixin"; -import formatDateTime from "../common/datetime/format_date_time"; +import { formatDateTimeWithSeconds } from "../common/datetime/format_date_time"; class StateHistoryChartLine extends LocalizeMixin(PolymerElement) { static get template() { @@ -317,7 +317,7 @@ class StateHistoryChartLine extends LocalizeMixin(PolymerElement) { const item = items[0]; const date = data.datasets[item.datasetIndex].data[item.index].x; - return formatDateTime(date, this.hass.language); + return formatDateTimeWithSeconds(date, this.hass.language); }; const chartOptions = { diff --git a/src/components/state-history-chart-timeline.js b/src/components/state-history-chart-timeline.js index ef0c91a87e..0ef2c6194c 100644 --- a/src/components/state-history-chart-timeline.js +++ b/src/components/state-history-chart-timeline.js @@ -6,7 +6,7 @@ import LocalizeMixin from "../mixins/localize-mixin"; import "./entity/ha-chart-base"; -import formatDateTime from "../common/datetime/format_date_time"; +import { formatDateTimeWithSeconds } from "../common/datetime/format_date_time"; import { computeRTL } from "../common/util/compute_rtl"; class StateHistoryChartTimeline extends LocalizeMixin(PolymerElement) { @@ -165,8 +165,8 @@ class StateHistoryChartTimeline extends LocalizeMixin(PolymerElement) { const formatTooltipLabel = (item, data) => { const values = data.datasets[item.datasetIndex].data[item.index]; - const start = formatDateTime(values[0], this.hass.language); - const end = formatDateTime(values[1], this.hass.language); + const start = formatDateTimeWithSeconds(values[0], this.hass.language); + const end = formatDateTimeWithSeconds(values[1], this.hass.language); const state = values[2]; return [state, start, end]; diff --git a/src/dialogs/more-info/controls/more-info-sun.ts b/src/dialogs/more-info/controls/more-info-sun.ts index f8bd512852..4cf93d0ed5 100644 --- a/src/dialogs/more-info/controls/more-info-sun.ts +++ b/src/dialogs/more-info/controls/more-info-sun.ts @@ -11,7 +11,7 @@ import { HassEntity } from "home-assistant-js-websocket"; import "../../../components/ha-relative-time"; -import formatTime from "../../../common/datetime/format_time"; +import { formatTime } from "../../../common/datetime/format_time"; import { HomeAssistant } from "../../../types"; @customElement("more-info-sun") diff --git a/src/panels/config/automation/ha-automation-picker.ts b/src/panels/config/automation/ha-automation-picker.ts index 608956c487..2de58ea69b 100644 --- a/src/panels/config/automation/ha-automation-picker.ts +++ b/src/panels/config/automation/ha-automation-picker.ts @@ -28,7 +28,7 @@ import { showAutomationEditor, AutomationConfig, } from "../../../data/automation"; -import format_date_time from "../../../common/datetime/format_date_time"; +import { formatDateTime } from "../../../common/datetime/format_date_time"; import { fireEvent } from "../../../common/dom/fire_event"; import { showThingtalkDialog } from "./show-dialog-thingtalk"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; @@ -102,7 +102,7 @@ class HaAutomationPicker extends LitElement { "ui.card.automation.last_triggered" )}: ${ automation.attributes.last_triggered - ? format_date_time( + ? formatDateTime( new Date(automation.attributes.last_triggered), this.hass.language ) diff --git a/src/panels/config/cloud/account/cloud-account.js b/src/panels/config/cloud/account/cloud-account.js index 19f37a5aff..6f3cacefa5 100644 --- a/src/panels/config/cloud/account/cloud-account.js +++ b/src/panels/config/cloud/account/cloud-account.js @@ -16,7 +16,7 @@ import "./cloud-remote-pref"; import { EventsMixin } from "../../../../mixins/events-mixin"; import { fetchCloudSubscriptionInfo } from "../../../../data/cloud"; -import formatDateTime from "../../../../common/datetime/format_date_time"; +import { formatDateTime } from "../../../../common/datetime/format_date_time"; import LocalizeMixin from "../../../../mixins/localize-mixin"; /* diff --git a/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts b/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts index 2964721dbf..89df7f4812 100644 --- a/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts +++ b/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts @@ -16,7 +16,7 @@ import { HaPaperDialog } from "../../../../components/dialog/ha-paper-dialog"; import { HomeAssistant } from "../../../../types"; import { haStyle } from "../../../../resources/styles"; import { CloudCertificateParams as CloudCertificateDialogParams } from "./show-dialog-cloud-certificate"; -import format_date_time from "../../../../common/datetime/format_date_time"; +import { formatDateTime } from "../../../../common/datetime/format_date_time"; @customElement("dialog-cloud-certificate") class DialogCloudCertificate extends LitElement { @@ -50,7 +50,7 @@ class DialogCloudCertificate extends LitElement { ${this.hass!.localize( "ui.panel.config.cloud.dialog_certificate.certificate_expiration_date" )} - ${format_date_time( + ${formatDateTime( new Date(certificateInfo.expire_date), this.hass!.language )}
diff --git a/src/panels/developer-tools/event/event-subscribe-card.ts b/src/panels/developer-tools/event/event-subscribe-card.ts index 7b89c464f4..4816672d59 100644 --- a/src/panels/developer-tools/event/event-subscribe-card.ts +++ b/src/panels/developer-tools/event/event-subscribe-card.ts @@ -13,7 +13,7 @@ import { HassEvent } from "home-assistant-js-websocket"; import { HomeAssistant } from "../../../types"; import { PolymerChangedEvent } from "../../../polymer-types"; import "../../../components/ha-card"; -import format_time from "../../../common/datetime/format_time"; +import { formatTime } from "../../../common/datetime/format_time"; @customElement("event-subscribe-card") class EventSubscribeCard extends LitElement { @@ -78,7 +78,7 @@ class EventSubscribeCard extends LitElement { "name", ev.id )} - ${format_time( + ${formatTime( new Date(ev.event.time_fired), this.hass!.language )}: diff --git a/src/panels/developer-tools/logs/system-log-card.ts b/src/panels/developer-tools/logs/system-log-card.ts index ab0f303ca5..1a03a72e1c 100644 --- a/src/panels/developer-tools/logs/system-log-card.ts +++ b/src/panels/developer-tools/logs/system-log-card.ts @@ -16,8 +16,8 @@ import "../../../components/buttons/ha-call-service-button"; import "../../../components/buttons/ha-progress-button"; import { HomeAssistant } from "../../../types"; import { LoggedError, fetchSystemLog } from "../../../data/system_log"; -import formatDateTime from "../../../common/datetime/format_date_time"; -import formatTime from "../../../common/datetime/format_time"; +import { formatDateTimeWithSeconds } from "../../../common/datetime/format_date_time"; +import { formatTimeWithSeconds } from "../../../common/datetime/format_time"; import { showSystemLogDetailDialog } from "./show-dialog-system-log-detail"; const formatLogTime = (date, language: string) => { @@ -26,8 +26,8 @@ const formatLogTime = (date, language: string) => { const dateTimeDay = new Date(date * 1000).setHours(0, 0, 0, 0); return dateTimeDay < today - ? formatDateTime(dateTime, language) - : formatTime(dateTime, language); + ? formatDateTimeWithSeconds(dateTime, language) + : formatTimeWithSeconds(dateTime, language); }; @customElement("system-log-card") diff --git a/src/panels/developer-tools/mqtt/mqtt-subscribe-card.ts b/src/panels/developer-tools/mqtt/mqtt-subscribe-card.ts index 24b40c1601..67d128ff7a 100644 --- a/src/panels/developer-tools/mqtt/mqtt-subscribe-card.ts +++ b/src/panels/developer-tools/mqtt/mqtt-subscribe-card.ts @@ -11,7 +11,7 @@ import "@material/mwc-button"; import "@polymer/paper-input/paper-input"; import { HomeAssistant } from "../../../types"; import "../../../components/ha-card"; -import format_time from "../../../common/datetime/format_time"; +import { formatTime } from "../../../common/datetime/format_time"; import { subscribeMQTTTopic, MQTTMessage } from "../../../data/mqtt"; @@ -85,7 +85,7 @@ class MqttSubscribeCard extends LitElement { "topic", msg.message.topic, "time", - format_time(msg.time, this.hass!.language) + formatTime(msg.time, this.hass!.language) )}
${msg.payload}
diff --git a/src/panels/history/ha-panel-history.js b/src/panels/history/ha-panel-history.js index 3daf0f4345..fcee278b61 100644 --- a/src/panels/history/ha-panel-history.js +++ b/src/panels/history/ha-panel-history.js @@ -16,7 +16,7 @@ import "../../data/ha-state-history-data"; import "../../resources/ha-date-picker-style"; import "../../resources/ha-style"; -import formatDate from "../../common/datetime/format_date"; +import { formatDate } from "../../common/datetime/format_date"; import LocalizeMixin from "../../mixins/localize-mixin"; import { computeRTL } from "../../common/util/compute_rtl"; diff --git a/src/panels/logbook/ha-logbook.ts b/src/panels/logbook/ha-logbook.ts index 86a0f8455a..6decd62cb2 100644 --- a/src/panels/logbook/ha-logbook.ts +++ b/src/panels/logbook/ha-logbook.ts @@ -1,6 +1,6 @@ import "../../components/ha-icon"; -import formatTime from "../../common/datetime/format_time"; -import formatDate from "../../common/datetime/format_date"; +import { formatTimeWithSeconds } from "../../common/datetime/format_time"; +import { formatDate } from "../../common/datetime/format_date"; import { domainIcon } from "../../common/entity/domain_icon"; import { stateIcon } from "../../common/entity/state_icon"; import { computeRTL } from "../../common/util/compute_rtl"; @@ -80,7 +80,7 @@ class HaLogbook extends LitElement {
- ${formatTime(new Date(item.when), this.hass.language)} + ${formatTimeWithSeconds(new Date(item.when), this.hass.language)}
string } = { - date: format_date, - datetime: format_date_time, - time: format_time, + date: formatDate, + datetime: formatDateTime, + time: formatTime, }; const INTERVAL_FORMAT = ["relative", "total"]; diff --git a/src/panels/mailbox/ha-panel-mailbox.js b/src/panels/mailbox/ha-panel-mailbox.js index c2710282e0..f1f3158d53 100644 --- a/src/panels/mailbox/ha-panel-mailbox.js +++ b/src/panels/mailbox/ha-panel-mailbox.js @@ -14,7 +14,7 @@ import "../../components/ha-menu-button"; import "../../components/ha-card"; import "../../resources/ha-style"; -import formatDateTime from "../../common/datetime/format_date_time"; +import { formatDateTime } from "../../common/datetime/format_date_time"; import LocalizeMixin from "../../mixins/localize-mixin"; import { EventsMixin } from "../../mixins/events-mixin"; diff --git a/src/panels/profile/ha-long-lived-access-tokens-card.js b/src/panels/profile/ha-long-lived-access-tokens-card.js index 68244c8d36..76af7c5c1b 100644 --- a/src/panels/profile/ha-long-lived-access-tokens-card.js +++ b/src/panels/profile/ha-long-lived-access-tokens-card.js @@ -4,7 +4,7 @@ import { html } from "@polymer/polymer/lib/utils/html-tag"; import { PolymerElement } from "@polymer/polymer/polymer-element"; import { EventsMixin } from "../../mixins/events-mixin"; import LocalizeMixin from "../../mixins/localize-mixin"; -import formatDateTime from "../../common/datetime/format_date_time"; +import { formatDateTime } from "../../common/datetime/format_date_time"; import "../../components/ha-card"; import "../../resources/ha-style"; diff --git a/src/panels/profile/ha-refresh-tokens-card.js b/src/panels/profile/ha-refresh-tokens-card.js index 59e87d703e..d3a4176e35 100644 --- a/src/panels/profile/ha-refresh-tokens-card.js +++ b/src/panels/profile/ha-refresh-tokens-card.js @@ -7,7 +7,7 @@ import { html } from "@polymer/polymer/lib/utils/html-tag"; import { PolymerElement } from "@polymer/polymer/polymer-element"; import { EventsMixin } from "../../mixins/events-mixin"; import LocalizeMixin from "../../mixins/localize-mixin"; -import formatDateTime from "../../common/datetime/format_date_time"; +import { formatDateTime } from "../../common/datetime/format_date_time"; import "./ha-settings-row"; diff --git a/test-mocha/common/datetime/format_date.ts b/test-mocha/common/datetime/format_date.ts index 2ef3162799..dab6dd5188 100644 --- a/test-mocha/common/datetime/format_date.ts +++ b/test-mocha/common/datetime/format_date.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; -import formatDate from "../../../src/common/datetime/format_date"; +import { formatDate } from "../../../src/common/datetime/format_date"; describe("formatDate", () => { const dateObj = new Date(2017, 10, 18, 11, 12, 13, 1400); diff --git a/test-mocha/common/datetime/format_date_time.ts b/test-mocha/common/datetime/format_date_time.ts index d909839b92..3cc331251e 100644 --- a/test-mocha/common/datetime/format_date_time.ts +++ b/test-mocha/common/datetime/format_date_time.ts @@ -1,9 +1,12 @@ import { assert } from "chai"; -import formatDateTime from "../../../src/common/datetime/format_date_time"; +import { + formatDateTime, + formatDateTimeWithSeconds, +} from "../../../src/common/datetime/format_date_time"; describe("formatDateTime", () => { - const dateObj = new Date(2017, 10, 18, 11, 12, 13, 1400); + const dateObj = new Date(2017, 10, 18, 11, 12, 13, 400); it("Formats English date times", () => { assert.strictEqual( @@ -12,3 +15,14 @@ describe("formatDateTime", () => { ); }); }); + +describe("formatDateTimeWithSeconds", () => { + const dateObj = new Date(2017, 10, 18, 11, 12, 13, 400); + + it("Formats English date times with seconds", () => { + assert.strictEqual( + formatDateTimeWithSeconds(dateObj, "en"), + "November 18, 2017, 11:12:13 AM" + ); + }); +}); diff --git a/test-mocha/common/datetime/format_time.ts b/test-mocha/common/datetime/format_time.ts index 4926e55663..98dfbb0568 100644 --- a/test-mocha/common/datetime/format_time.ts +++ b/test-mocha/common/datetime/format_time.ts @@ -1,6 +1,9 @@ import { assert } from "chai"; -import formatTime from "../../../src/common/datetime/format_time"; +import { + formatTime, + formatTimeWithSeconds, +} from "../../../src/common/datetime/format_time"; describe("formatTime", () => { const dateObj = new Date(2017, 10, 18, 11, 12, 13, 1400); @@ -9,3 +12,11 @@ describe("formatTime", () => { assert.strictEqual(formatTime(dateObj, "en"), "11:12 AM"); }); }); + +describe("formatTimeWithSeconds", () => { + const dateObj = new Date(2017, 10, 18, 11, 12, 13, 400); + + it("Formats English times with seconds", () => { + assert.strictEqual(formatTimeWithSeconds(dateObj, "en"), "11:12:13 AM"); + }); +});