: * 它的显示格式由**浏览器 UI 语言 / 系统时间格式**决定, 与元素 lang * 都压不过它。中文环境实测会渲染成「下午 03:30」,用户很容易把上下午填反; * 而且它只有时:分,**没有秒**。拆成「原生日期选择器 + 三个下拉」后, * 24 小时制与"精确到秒"都由控件本身保证,浏览器改不掉。 * * 日期部分仍是原生 ``(app.js 里的 showPicker 脚本对它同样生效, * 点输入框任意位置都能弹出日历 —— 这正是"整个输入框点击都可以弹出"的落点)。 * * 用法(include 前 set 好这些变量;模板里只读它们): * $dtName 字段基名,如 'birthday_solar' → 产出 *_date / _hour / _minute / _second * $dtValue 可空;'Y-m-d H:i:s' / 'Y-m-d H:i' / 'Y-m-d'。服务端用 read_dt_input($dtName) 取值 * $dtRequired 日期是否必填(默认 false) * $dtId 可选;日期控件的 id(供 ) * $dtSeconds 是否要"秒"这一档(默认 true;生日要精确到时分秒) */ $dtName = (string)($dtName ?? 'time'); $dtValue = $dtValue ?? null; $dtRequired = (bool)($dtRequired ?? false); $dtId = (string)($dtId ?? ''); $dtSeconds = (bool)($dtSeconds ?? true); /* 用户 2026-10-04 第 7 条原话:「所有的时间选择,都已更换新插件,但是有个问题, 如果是选择一个时间范围的情况,就是说,有开始时间,有结束时间,应该用这个日期插件的 时间范围选择方式,而不是将这个范围拆成两个,这样不好看,也多一步操作。」 → 有起止两端的场景不再并列两个控件,而是**一个范围控件**。 实现方式是"服务端照旧渲染两个原生控件(表单契约/e2e 都不动), 由 app.js 在升级时识别成一对、只挂一个 Semi 范围选择器"。所以这里只加标记: $dtRange = 'start' | 'end' —— 这对控件属于同一个范围(调用方还要用 把两者包在一起,见 movies/form.php 等)。 留空 = 普通单点控件(默认,行为完全不变)。 */ $dtRange = (string)($dtRange ?? ''); // ⚠️⚠️ 临时变量**一律带 dt 前缀**,一个都不能漏:这里原来写成 // `$t = strtotime(...)`,把宿主模板里表示「这条任务 / 这条记录」的 `$t` // 覆盖成了 int —— 于是 include 之后凡是读 `$t['id']`、`$t['status']` 的地方 // 全部拿到 null,子任务列表空、评论不渲染、@高亮消失,而且**不报任何错** // (PHP 8 对 "Trying to access array offset on value of type int" 只 Warning)。 // tasks/show.php 上就是这么被 e2e 抓到的(2026-10-02)。 $dtTs = (!empty($dtValue) && ($dtTsTmp = strtotime(trim((string)$dtValue)))) ? $dtTsTmp : false; $dtDate = $dtTs ? date('Y-m-d', $dtTs) : ''; $dtHour = $dtTs ? (int)date('G', $dtTs) : 0; // G = 0..23,天然 24 小时制 $dtMin = $dtTs ? (int)date('i', $dtTs) : 0; $dtSec = $dtTs ? (int)date('s', $dtTs) : 0; ?> $dtName, 'seconds' => $dtSeconds, 'required' => $dtRequired, 'id' => $dtId, 'range' => $dtRange]; ?> value="= e($dtDate) ?>"= $dtRequired ? ' required' : '' ?> aria-label="日期"> >= $hv ?> : >= $mv ?> : >= $sv ?>