先记住这个答案
时间输入的 step 以秒计,60 是一分钟,900 是十五分钟。合法值不仅取决于间隔,还取决于步进基准:若 min="09:05" 且 step="900",允许时间从 09:05、09:20、09:35 这样推进。浏览器原生选择器显示哪些分钟选项可能不同,但最终应看约束校验结果,而不是只看 UI 有没有隐藏某个时间。
- 时间
step的单位是秒 60对应一分钟步长900对应十五分钟步长- 合法刻度需结合步进基准
预约时间从营业开始算
门店 09:05 开始接待,每 15 分钟开放一个时段。若误以为 step="900" 永远锁定在整点后的 00、15、30、45 分,就会错误拒绝 09:20。
<label for="slot">预约时间</label>
<input id="slot" name="slot" type="time"
min="09:05" max="17:05" step="900" required>这里 900 秒等于 15 分钟,步进基准是 min,所以 09:05、09:20 等值符合步进。若用户填 09:10,虽然处于营业范围内,却会出现 stepMismatch。
若不设置 min,步进基准还可能受初始值等规则影响。关键业务场景应显式设置 min 与 step,不要靠默认刻度猜测。
选择器外观与数据约束分开
浏览器对时间输入可能显示滚轮、下拉列表或系统原生面板。有的界面只呈现部分候选,有的仍允许键盘编辑;不能只根据可见选项判断所有值是否合法。
脚本可读取 input.validity.stepMismatch,也要检查 rangeUnderflow 和 rangeOverflow。服务端收到的是时间字符串,还应验证营业时间、预约名额和时区相关业务规则;原生 time 值本身不携带日期或时区。
当 step 不是 60 的整数倍,例如写 step="30",合法值可能带秒,控件界面也可能出现秒输入区;提交字符串因此不一定只有 HH:mm,还可能是 HH:mm:ss。夜间门店还可能用晚于 max 的 min 表达跨午夜时段,不能简单把时间字符串当普通数字区间比较。最后,time 值始终不带日期或时区;跨地区预约必须另有日期和明确时区,才能确定真实时刻。
如果要写脚本展示预约刻度,可通过 input.value 读取规范化字符串,再按业务规则解析。不要从操作系统时间面板上读显示文本:12 小时制界面可能显示上午、下午,但提交值仍按标准格式表示。脚本调用 stepUp() 也会依照控件的基准和步长推进,适合做“下一个时段”按钮;实际可预约名额仍需向服务器确认。
容易答错的地方
- 把
step="900"当成 900 分钟 - 对
time来说单位是秒,900 秒是 15 分钟。 - 以为原生面板会在所有浏览器里隐藏非法分钟
- 控件外观和输入路径各异,最终以值与约束校验为准。
面试官还会怎么问?
step="any" 有什么用?
取消步进间隔限制;min、max 等其他约束仍可生效。
time 值带日期或时区吗?
不带,它表示一天中的时间字符串。预约日期与时区要由其他字段或业务逻辑确定。
为什么 09:10 在这个例子里不合法?
它比 09:05 只晚五分钟,不能写成 15 分钟步长的整数倍。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。