From dd636bbe03c11cb06d4963c0f0a0e68e56c96f34 Mon Sep 17 00:00:00 2001
From: tajniak81 <13187254+tajniak81@users.noreply.github.com>
Date: Thu, 3 Sep 2026 21:13:42 +0200
Subject: [PATCH] A time box that reads on the clock the user chose
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The schedule windows met this account with "12:00 AM", clipped to
"12:00 A!" by a box too narrow for it, while the card above them printed
00:00. Both halves of that are the native control:
renders in the browser's locale, and its am/pm did not fit.
Nothing on the page moves it. lang= was measured rather than assumed —
five inputs set to en-US, en-GB, da-DK, pl-PL and nothing came out
identically wide, because the control follows navigator.languages and not
the document. That is the wall DateField hit for dates, so the answer has
its shape: the typing half is ours, the value stays 24-hour "HH:MM", and
what the box shows follows the setting.
Four digits, the colon inserted as they are typed, the meridiem its own
control rather than something to spell. No picker button: a calendar
earns one, four digits do not, and the browser's popup would have brought
the 12-hour reading back in with it. A half-typed or impossible time
emits nothing rather than the part of it that parses, so a block's Apply
leaves that field out instead of writing a time nobody meant.
format.js exports which clock is in force now, so what prints a time and
what accepts one cannot disagree about it.
The box is 80px because 12:30 measures 66 with its padding and the first
attempt at 64 clipped — which was the complaint.
Co-Authored-By: Claude Opus 5
---
Web App/web/src/components/TimeField.vue | 147 +++++++++++++++++++++++
Web App/web/src/lib/format.js | 18 ++-
Web App/web/src/views/Charging.vue | 10 +-
3 files changed, 165 insertions(+), 10 deletions(-)
create mode 100644 Web App/web/src/components/TimeField.vue
diff --git a/Web App/web/src/components/TimeField.vue b/Web App/web/src/components/TimeField.vue
new file mode 100644
index 0000000..3a70f69
--- /dev/null
+++ b/Web App/web/src/components/TimeField.vue
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
+
diff --git a/Web App/web/src/lib/format.js b/Web App/web/src/lib/format.js
index 4fafc0b..3a38a78 100644
--- a/Web App/web/src/lib/format.js
+++ b/Web App/web/src/lib/format.js
@@ -109,13 +109,25 @@ export function formatTime(value) {
const pad = (n) => String(n).padStart(2, "0");
const mm = pad(d.getMinutes());
- const mode = prefs.timeFormat;
- const twelve = mode === "12" || (mode !== "24" && regionReadsTwelveHour());
- if (!twelve) return `${pad(h)}:${mm}`;
+ if (!clockIsTwelveHour()) return `${pad(h)}:${mm}`;
// 12 for both noon and midnight, and midnight is the am one.
return `${pad(h % 12 || 12)}:${mm} ${h < 12 ? "am" : "pm"}`;
}
+// Whether times are written on a 12-hour clock right now: what the setting says
+// outright, or what the region says when it is left on auto.
+//
+// Exported because printing a time is not the only thing that has to know. A
+// control that lets somebody *enter* one has to offer the same clock, and a box
+// that reads 13:45 beside a picker that says 01:45 PM is the disagreement this
+// setting exists to end (see components/TimeField.vue).
+export function clockIsTwelveHour() {
+ const mode = prefs.timeFormat;
+ if (mode === "12") return true;
+ if (mode === "24") return false;
+ return regionReadsTwelveHour();
+}
+
// Whether the chosen region tells the time on a 12-hour clock — the one question
// "auto" asks it. Cached because this is asked once per timestamp on a page that
// can hold a great many, and the answer only changes when the region does.
diff --git a/Web App/web/src/views/Charging.vue b/Web App/web/src/views/Charging.vue
index 46d7e5f..fe4baeb 100644
--- a/Web App/web/src/views/Charging.vue
+++ b/Web App/web/src/views/Charging.vue
@@ -5,6 +5,7 @@ import { prefs } from "../prefs";
import { askConfirm } from "../lib/confirm.js";
import { api } from "../api";
import { formatDateTime } from "../lib/format.js";
+import TimeField from "../components/TimeField.vue";
import { CHARGING_TABS, defaultTabFor } from "../lib/tabs.js";
import ChargerImportModal from "../components/ChargerImportModal.vue";
@@ -2592,18 +2593,13 @@ onMounted(async () => {
-
–
-