From f4f13fc68d070ff5b1dc281288cbbbe492f10777 Mon Sep 17 00:00:00 2001 From: Andy Chiang Date: Thu, 16 Oct 2025 00:48:26 +0700 Subject: [PATCH 1/4] luci-mod-status: use localized time use localized time Signed-off-by: Andy Chiang --- .../view/status/include/10_system.js | 35 ++++++++++++------- .../rpcd/acl.d/luci-mod-status-index.json | 2 +- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/10_system.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/10_system.js index 45f7b4acae6d..4c7876d5b921 100644 --- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/10_system.js +++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/10_system.js @@ -2,6 +2,13 @@ 'require baseclass'; 'require fs'; 'require rpc'; +'require uci'; + +var callGetUnixtime = rpc.declare({ + object: 'luci', + method: 'getUnixtime', + expect: { result: 0 } +}); var callLuciVersion = rpc.declare({ object: 'luci', @@ -25,30 +32,34 @@ return baseclass.extend({ return Promise.all([ L.resolveDefault(callSystemBoard(), {}), L.resolveDefault(callSystemInfo(), {}), - L.resolveDefault(callLuciVersion(), { revision: _('unknown version'), branch: 'LuCI' }) + L.resolveDefault(callLuciVersion(), { revision: _('unknown version'), branch: 'LuCI' }), + L.resolveDefault(callGetUnixtime(), 0), + uci.load('system') ]); }, render: function(data) { var boardinfo = data[0], systeminfo = data[1], - luciversion = data[2]; + luciversion = data[2], + unixtime = data[3]; luciversion = luciversion.branch + ' ' + luciversion.revision; var datestr = null; - if (systeminfo.localtime) { - var date = new Date(systeminfo.localtime * 1000); + if (unixtime) { + var date = new Date(unixtime * 1000), + zn = uci.get('system', '@system[0]', 'zonename')?.replaceAll(' ', '_') || 'UTC', + ts = uci.get('system', '@system[0]', 'clock_timestyle'), + hc = uci.get('system', '@system[0]', 'clock_hourcycle'); - datestr = '%04d-%02d-%02d %02d:%02d:%02d'.format( - date.getUTCFullYear(), - date.getUTCMonth() + 1, - date.getUTCDate(), - date.getUTCHours(), - date.getUTCMinutes(), - date.getUTCSeconds() - ); + datestr = new Intl.DateTimeFormat(undefined, { + dateStyle: 'medium', + timeStyle: (ts == 0) ? 'long' : 'full', + hourCycle: hc, + timeZone: zn + }).format(date); } var fields = [ diff --git a/modules/luci-mod-status/root/usr/share/rpcd/acl.d/luci-mod-status-index.json b/modules/luci-mod-status/root/usr/share/rpcd/acl.d/luci-mod-status-index.json index c9e3c836cb9e..f2253f39c0ec 100644 --- a/modules/luci-mod-status/root/usr/share/rpcd/acl.d/luci-mod-status-index.json +++ b/modules/luci-mod-status/root/usr/share/rpcd/acl.d/luci-mod-status-index.json @@ -9,7 +9,7 @@ "/www/luci-static/resources/view/status/include": [ "list" ] }, "ubus": { - "luci": [ "getVersion" ], + "luci": [ "getVersion", "getUnixtime" ], "file": [ "list", "read" ], "system": [ "board", "info" ] } From f12ab2fc14d14573e65a1b8d106a4285e66accca Mon Sep 17 00:00:00 2001 From: Andy Chiang Date: Thu, 16 Oct 2025 00:48:45 +0700 Subject: [PATCH 2/4] luci-mod-system: use localized time use localized time Signed-off-by: Andy Chiang --- .../resources/view/system/system.js | 47 +++++++++++-------- .../usr/share/rpcd/acl.d/luci-mod-system.json | 5 +- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/system.js b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/system.js index 2ed2b1fedbcc..40110f62f020 100644 --- a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/system.js +++ b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/system.js @@ -8,7 +8,7 @@ 'require tools.widgets as widgets'; var callRcList, callRcInit, callTimezone, - callGetLocaltime, callSetLocaltime, CBILocalTime; + callGetUnixtime, callSetLocaltime, CBILocalTime; callRcList = rpc.declare({ object: 'rc', @@ -29,10 +29,10 @@ callRcInit = rpc.declare({ expect: { result: false } }); -callGetLocaltime = rpc.declare({ - object: 'system', - method: 'info', - expect: { localtime: 0 } +callGetUnixtime = rpc.declare({ + object: 'luci', + method: 'getUnixtime', + expect: { result: 0 } }); callSetLocaltime = rpc.declare({ @@ -49,16 +49,17 @@ callTimezone = rpc.declare({ }); function formatTime(epoch) { - var date = new Date(epoch * 1000); - - return '%04d-%02d-%02d %02d:%02d:%02d'.format( - date.getUTCFullYear(), - date.getUTCMonth() + 1, - date.getUTCDate(), - date.getUTCHours(), - date.getUTCMinutes(), - date.getUTCSeconds() - ); + var date = new Date(epoch * 1000), + zn = uci.get('system', '@system[0]', 'zonename')?.replaceAll(' ', '_') || 'UTC', + ts = uci.get('system', '@system[0]', 'clock_timestyle'), + hc = uci.get('system', '@system[0]', 'clock_hourcycle'); + + return new Intl.DateTimeFormat(undefined, { + dateStyle: 'medium', + timeStyle: (ts == 0) ? 'long' : 'full', + hourCycle: hc, + timeZone: zn + }).format(date); } CBILocalTime = form.DummyValue.extend({ @@ -97,7 +98,7 @@ return view.extend({ return Promise.all([ callRcList('sysntpd'), callTimezone(), - callGetLocaltime(), + callGetUnixtime(), uci.load('luci'), uci.load('system') ]); @@ -106,7 +107,7 @@ return view.extend({ render: function(rpc_replies) { var ntpd_enabled = rpc_replies[0], timezones = rpc_replies[1], - localtime = rpc_replies[2], + unixtime = rpc_replies[2], m, s, o; m = new form.Map('system', @@ -129,7 +130,7 @@ return view.extend({ */ o = s.taboption('general', CBILocalTime, '_systime', _('Local Time')); - o.cfgvalue = function() { return localtime }; + o.cfgvalue = function() { return unixtime }; o.ntpd_support = ntpd_enabled; o = s.taboption('general', form.Value, 'hostname', _('Hostname')); @@ -155,6 +156,14 @@ return view.extend({ uci.set('system', section_id, 'timezone', tz); }; + o = s.taboption('general', form.Flag, 'clock_timestyle', _('Full TimeZone Name'), _('Unchecked means the timezone offset (E.g. GMT+1) is displayed')); + o.default = o.enabled; + + o = s.taboption('general', form.ListValue, 'clock_hourcycle', _('Time Format')); + o.value('', _('Default')); + o.value('h12', _('12-Hour Clock')); + o.value('h23', _('24-Hour Clock')); + /* * Logging */ @@ -309,7 +318,7 @@ return view.extend({ return m.render().then(function(mapEl) { poll.add(function() { - return callGetLocaltime().then(function(t) { + return callGetUnixtime().then(function(t) { mapEl.querySelector('#localtime').value = formatTime(t); }); }); diff --git a/modules/luci-mod-system/root/usr/share/rpcd/acl.d/luci-mod-system.json b/modules/luci-mod-system/root/usr/share/rpcd/acl.d/luci-mod-system.json index c61338893b85..379d89fc6fcb 100644 --- a/modules/luci-mod-system/root/usr/share/rpcd/acl.d/luci-mod-system.json +++ b/modules/luci-mod-system/root/usr/share/rpcd/acl.d/luci-mod-system.json @@ -3,9 +3,8 @@ "description": "Grant access to system configuration", "read": { "ubus": { - "luci": [ "getLEDs", "getTimezones", "getUSBDevices" ], - "rc": [ "list" ], - "system": [ "info" ] + "luci": [ "getLEDs", "getTimezones", "getUSBDevices", "getUnixtime" ], + "rc": [ "list" ] }, "uci": [ "luci", "system" ] }, From 1d4498604c2d2ef82cef86c69a84c1e64bcf5686 Mon Sep 17 00:00:00 2001 From: Andy Chiang Date: Thu, 16 Oct 2025 00:48:55 +0700 Subject: [PATCH 3/4] luci-mod-dashboard: use localized time use localized time Signed-off-by: Andy Chiang --- .../view/dashboard/include/10_router.js | 35 ++++++++++++------- .../share/rpcd/acl.d/luci-mod-dashboard.json | 1 + 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js b/modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js index d97fc9cadf93..8005ff67448f 100644 --- a/modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js +++ b/modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js @@ -3,6 +3,7 @@ 'require fs'; 'require rpc'; 'require network'; +'require uci'; var callSystemBoard = rpc.declare({ object: 'system', @@ -14,6 +15,12 @@ var callSystemInfo = rpc.declare({ method: 'info' }); +var callGetUnixtime = rpc.declare({ + object: 'luci', + method: 'getUnixtime', + expect: { result: 0 } +}); + return baseclass.extend({ params: [], @@ -23,7 +30,9 @@ return baseclass.extend({ network.getWANNetworks(), network.getWAN6Networks(), L.resolveDefault(callSystemBoard(), {}), - L.resolveDefault(callSystemInfo(), {}) + L.resolveDefault(callSystemInfo(), {}), + L.resolveDefault(callGetUnixtime(), 0), + uci.load('system') ]); }, @@ -298,20 +307,22 @@ return baseclass.extend({ const boardinfo = data[2]; const systeminfo = data[3]; + const unixtime = data[4]; let datestr = null; - if (systeminfo.localtime) { - const date = new Date(systeminfo.localtime * 1000); - - datestr = '%04d-%02d-%02d %02d:%02d:%02d'.format( - date.getUTCFullYear(), - date.getUTCMonth() + 1, - date.getUTCDate(), - date.getUTCHours(), - date.getUTCMinutes(), - date.getUTCSeconds() - ); + if (unixtime) { + const date = new Date(unixtime * 1000); + const zn = uci.get('system', '@system[0]', 'zonename')?.replaceAll(' ', '_') || 'UTC'; + const ts = uci.get('system', '@system[0]', 'clock_timestyle'); + const hc = uci.get('system', '@system[0]', 'clock_hourcycle'); + + datestr = new Intl.DateTimeFormat(undefined, { + dateStyle: 'medium', + timeStyle: (ts == 0) ? 'long' : 'full', + hourCycle: hc, + timeZone: zn + }).format(date); } this.params.router = { diff --git a/modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json b/modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json index 1f331e7b4b81..023122a3c24f 100644 --- a/modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json +++ b/modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json @@ -16,6 +16,7 @@ }, "ubus": { "file": [ "list", "read" ], + "luci": [ "getUnixtime" ], "system": [ "board", "info" ] } } From ba98caeadb057de7a746d669bd504de3d32db999 Mon Sep 17 00:00:00 2001 From: Andy Chiang Date: Fri, 17 Oct 2025 20:43:36 +0700 Subject: [PATCH 4/4] luci-theme-bootstrap: add width for localtime set an appropriate width for #localtime Signed-off-by: Andy Chiang --- .../htdocs/luci-static/bootstrap/cascade.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css b/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css index c1be937697f9..1b94ad7a1dbe 100644 --- a/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css +++ b/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css @@ -589,6 +589,12 @@ select, border-radius: 3px; } +@media screen and (min-width: 768px) { + #localtime { + width: 300px; + } +} + input, select, .cbi-select,