The clock stops being a side effect of the region

Whether a time read as 13.45 or 01.45 pm was decided by the region
picker, which also sets the decimal separator and the currency layout —
so a Dane who wanted a 12-hour clock had to move their numbers to get
one. Time format is its own setting now, beside the date format it is
the other half of.

It defaults to "auto", the region's own convention, which is what every
timestamp in the app already said: nothing moves until somebody picks
something. The 24-hour setting asks for hourCycle h23 rather than
hour12:false, because with hour12 the en-US formatter prints midnight as
24:00.

One helper, so it reaches everywhere at once: formatDateTime now calls
formatTime, and every clock the app draws goes through it — the
charger's telemetry and settings, a session's start, when a charger was
linked, the provider panel's own timestamp.

The users collection gains a time_format select in both places the
schema is declared; it is in reconcileOrder, so a restart adds the field
and nothing has to be migrated by hand.

The native time inputs in the charger's settings card are left alone:
the browser renders those in the OS convention whatever this says, and a
text box that respected the setting would be the worse control.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tajniak81
2026-09-03 18:32:52 +02:00
co-authored by Claude Opus 5
parent 3fddab6815
commit dde5410788
10 changed files with 78 additions and 3 deletions
+15
View File
@@ -29,6 +29,7 @@ type userRecord struct {
Theme string `json:"theme"`
Locale string `json:"locale"`
DateFormat string `json:"date_format"`
TimeFormat string `json:"time_format"`
Currency string `json:"currency"`
FontSize string `json:"font_size"`
DragLocked bool `json:"drag_locked"`
@@ -97,6 +98,7 @@ func (rec userRecord) toModel() models.User {
Theme: orDefault(rec.Theme, "system"),
Locale: orDefault(rec.Locale, "en-US"),
DateFormat: orDefault(rec.DateFormat, "YMD"),
TimeFormat: orDefault(rec.TimeFormat, "auto"),
Currency: orDefault(rec.Currency, "USD"),
FontSize: orDefault(rec.FontSize, "medium"),
DragLocked: rec.DragLocked,
@@ -161,6 +163,7 @@ type updateMeRequest struct {
Theme *string `json:"theme"`
Locale *string `json:"locale"`
DateFormat *string `json:"dateFormat"`
TimeFormat *string `json:"timeFormat"`
Currency *string `json:"currency"`
FontSize *string `json:"fontSize"`
DragLocked *bool `json:"dragLocked"`
@@ -256,6 +259,11 @@ func normalizeOrder(field string, in []string, max int) ([]string, error) {
var validThemes = map[string]bool{"light": true, "dark": true, "system": true}
var validDateFormats = map[string]bool{"YMD": true, "DMY_NUM": true, "DMY": true, "MDY": true}
// "auto" reads the clock the way the chosen region writes it, which is what
// the app did before there was a setting; the other two say it outright, for
// the people whose region and habit disagree.
var validTimeFormats = map[string]bool{"auto": true, "24": true, "12": true}
var validFontSizes = map[string]bool{"small": true, "medium": true, "large": true}
// Kept in step with the users.currency select options in setup-pocketbase.mjs:
@@ -318,6 +326,13 @@ func (s *Server) handleUpdateMe(w http.ResponseWriter, r *http.Request) {
}
payload["date_format"] = *in.DateFormat
}
if in.TimeFormat != nil {
if !validTimeFormats[*in.TimeFormat] {
writeError(w, http.StatusBadRequest, "timeFormat must be auto, 24, or 12")
return
}
payload["time_format"] = *in.TimeFormat
}
if in.Currency != nil {
if !validCurrencies[*in.Currency] {
writeError(w, http.StatusBadRequest, "currency must be a supported ISO 4217 code")
+3
View File
@@ -231,6 +231,9 @@ var collectionsSchema = map[string][]fieldDef{
fSelect("theme", []string{"light", "dark", "system"}, false),
fText("locale", false),
fSelect("date_format", []string{"YMD", "DMY_NUM", "DMY", "MDY"}, false),
// "auto" is the region's own convention, which is what every clock in the
// app read before this field existed.
fSelect("time_format", []string{"auto", "24", "12"}, false),
fSelect("currency", []string{
"EUR", "GBP", "CHF", "PLN", "CZK", "HUF", "RON", "BGN", "DKK", "SEK", "NOK",
"ISK", "ALL", "AMD", "AZN", "BAM", "BYN", "GEL", "MDL", "MKD", "RSD", "RUB",
+1
View File
@@ -476,6 +476,7 @@ type User struct {
Theme string `json:"theme"` // light | dark | system
Locale string `json:"locale"` // e.g. "en-US"
DateFormat string `json:"dateFormat"` // YMD | DMY | MDY
TimeFormat string `json:"timeFormat"` // auto (the region's own) | 24 | 12
Currency string `json:"currency"` // ISO 4217 code, e.g. "EUR"
FontSize string `json:"fontSize"` // small | medium | large
Role string `json:"role"` // user | admin