<label for="appt">Choose a time for your meeting:</label>
<input type="time" id="appt" name="appt" min="09:00" max="18:00" required />
<small>Office hours are 9am to 6pm</small>
label {
  display: block;
  font:
    1rem "Fira Sans",
    sans-serif;
input,
label {
  margin: 0.4rem 0;
    

Chrome 和 Opera

在 Chrome 或 Opera 中,time 选择控件很简单,根据操作系统区域设置,插槽以 12 或 24 小时格式输入小时和分钟,上下箭头用于递增和递减当前选定的组件。在某些版本中,会提供一个“x”按钮来清除控件的值。

12 小时制输入格式 12 小时制

24 小时制输入格式 24 小时制

Firefox

Firefox 的 time 选择控件和 Chrome 非常相似,只是它没有上下箭头。它还基于系统区域设置使用 12 或 24 小时格式输入时间,也提供“X”按钮以清除控件的值。

Firefox 的 12 小时制输入格式 12 小时制

Firefox 的 24 小时制输入格式 24 小时制

Edge 的 time 选择控件有点复杂,打开一个小时和分钟的滚动区域。它和 Chrome 一样,基于系统区域设置使用 12 或 24 小时格式输入时间:

Edge 的 12 小时制输入格式 12 小时制

Edge 的 24 小时制输入格式 24 小时制

一个代表时间的字符串,或为空字符串。 changeinput 支持的常用属性 autocompletelistreadonlystep IDL 属性 valuevalueAsDatevalueAsNumberlist DOM 接口 HTMLInputElement select()stepDown()stepUp()

设置 value 属性

你可以通过在创建 <input> 元素时在 value 属性包含一个合法的时间来设置默认值,比如:

html
<label for="appt-time">选择约定的时间:</label>
<input id="appt-time" type="time" name="appt-time" value="13:30" />
    

使用 JavaScript 设置 value

你也可以在 JavaScript 代码中通过 HTMLInputElementvalue 属性获取和设置时间的值,比如:

js
const timeControl = document.querySelector('input[type="time"]');
timeControl.value = "15:30";
    

time 输入框无论输入何种格式的值(这可能由用户的区域设置,或用户代理决定),其 value 值总是带有前导零的 24 小时制时间:hh:mm。如果输入的时间包含秒数(参见使用 step 属性),则格式总是为 hh:mm:ss。你可以在时间字符串中了解到更多有关时间值的格式。

在此示例中,你可以通过输入时间并查看之后如何更改来查看时间输入的值。

首先,看一下 HTML。这很简单,带有我们之前看到的标签和输入控件,但添加了额外的元素 <p><span> 用来显示 time 控件的值:

html
<form>
  <label for="startTime">开始时间:</label>
  <input type="time" id="startTime" />
    <code>time</code> 输入框的值: <code> "<span id="value">n/a</span>"</code>.
</form>

这段 JavaScript 代码将代码添加到时间 input 中,以监听 input 事件,每次 input 元素的内容发生变化时都会触发该事件。每次事件触发时,<span> 元素的内容都会替换为 input 元素的最新值。

js
const startTime = document.getElementById("startTime");
const valueSpan = document.getElementById("value");
startTime.addEventListener(
  "input",
  () => {
    valueSpan.innerText = startTime.value;
  false,

当包含 time 输入框的表单被提交后,该值在被包含在表单数据中之前被编码。表单的时间输入数据总是以 name=hh%3Amm 的形式出现,如果包含秒数,则以 name=hh%3Amm%3Ass 的形式出现(参见使用 step 属性)。

除了 <input> 元素共有的属性外,时间输入还提供以下属性:

与许多数据类型不同,时间值有一个周期域,意味着数值达到可能的最高值之后,就会绕回起点。例如,指定 min14:00max2:00 意味着允许的时间值从下午 2:00 开始,通过午夜运行到第二天,结束于凌晨 2:00。更多信息请参见本文的使最小值和最大值跨越午夜部分。

列表属性的值是位于同一文档中的 <datalist> 元素的 id<datalist> 提供了一个预定义的值列表,向用户建议这个输入。列表中任何与 type 不兼容的值都不包括在建议选项中。所提供的值是建议,不是要求:用户可以从这个预定义的列表中选择,或者提供不同的值。

一个代表所接受的最迟时间的字符串,使用上述的时间格式指定。如果指定的字符串不是合法的时间表示,则不会设置最大值。

一个代表所接受的最早时间的字符串,使用上述的时间格式指定。如果指定的字符串不是合法的时间表示,则不会设置最小值。

readonly

如果该布尔属性存在,意味着用户将不能编辑此字段。然而其 value 值仍然可以直接通过 JavaScript 代码设置 HTMLInputElementvalue 属性改变。

由于只读字段不可以拥有值,required 不会对指定了 readonly 属性的字段起作用。

step 属性指定了值必须满足的粒度,或者是下文描述的特殊值 any。值必须满足基础的步进值,才有效。如果指定了 min 属性,则由 min 属性决定,否则,使用 value 属性的值,如果上述两个值都不存在,则提供适当的默认值。

字符串值 any 意味着不使用步进值,任意值都可以接受(除其他制约因素如 minmax 之外)。

当用户输入的数据不符合步进配置时,用户代理可能会四舍五入到最近的有效值,当有两个同样接近的选项时,更倾向于正方向的数字。

对于 time 输入, step 的值以秒为单位,比例因子为 1000(因为基础数值以毫秒为单位)。step 的默认值为 60,表示 60 秒(或 1 分钟、60000 毫秒)。

目前,尚不清楚当与 time 输入一起使用时,any 的值对 step 意味着什么。确定该信息后,将对其进行更新。

使用 time 输入

time 的基本用法

<input type="time"> 的最简单用法涉及基本的 <input><label> 元素组合,如下所示:

html
<form>
  <label for="appt-time">选择约定的时间:</label>
  <input id="appt-time" type="time" name="appt-time" />
</form>
    

控制输入框大小

<input type="time"> 不支持诸如 size 的表单大小属性,因为时间字符串的长度总是相同的。你必须依靠 CSS 来确定大小。

使用 step 属性

你可以使用 step 属性来更改每次递增或递减的时间数(例如,点击箭头控件时时间值会以 10 分钟为单位变动)。

此属性在不同浏览器之间有一些怪异的行为,并不可靠。

它需要一个整数,相当于你要增加的秒数;默认值是 60 秒,或 1 分钟。如果你指定一个小于 60 秒(1 分钟)的值,time 输入将显示秒的输入区,同时显示小时和分钟。

html
<form>
  <label for="appt-time">选择约定的时间:</label>
  <input id="appt-time" type="time" name="appt-time" step="2" />
</form>

在 Chrome 和 Opera 这两个为数不多显示上下迭代箭头的浏览器中,点击箭头可以将秒的数值改变两秒,但不会影响小时或分钟。分(或小时)只有在你指定了以秒为单位的分钟(或小时)数时,才能用于步进,比如 120 代表 2 分钟,7200 代表 2 小时)。

在 Firefox 浏览器中,没有箭头,所以没有使用 step 值。然而,提供它在分钟部分的旁边增加秒数输入区。

在 Edge 浏览器中,step 值不起作用。

使用 step 可能会导致验证工作不正常(如下一节所见)。

默认情况下,<input type="time"> 不会对输入的值应用任何验证,用户代理接口会屏蔽所有非时间值的输入,尽管这很有用(假设用户代理完全支持 time 输入),但是仍然无法完全依赖于该值的合法性。它仍然允许空字符串(""),且可能允许那些看起来像,但并不正确的时间值(如 25:05)。

设置最大和最小时间

你可以使用 minmax 属性来限制用户可以选择的有效时间。在以下示例中,我们设置了可供选择的最小值 12:00 和最大值 18:00

html
<form>
  <label for="appt-time"> 选择约定的时间(开放时间为 12:00 到 18:00): </label>
  <input id="appt-time" type="time" name="appt-time" min="12:00" max="18:00" />
  <span class="validity"></span>
</form>

下面是上述例子中使用的 CSS。这里我们使用了 :valid:invalid 这两个 CSS 属性,根据当前值是否有效来为输入添加样式。我们不得不把图标放在 input 旁边的 <span> 上,而不是放在 input 框本身,因为在 Chrome 中,生成的内容被放在表单控件里面,无法有效地进行样式设计或显示。

css
div {
  margin-bottom: 10px;
  position: relative;
input[type="number"] {
  width: 100px;
input + span {
  padding-right: 30px;
input:invalid + span::after {
  position: absolute;
  content: "✖";
  padding-left: 5px;
input:valid + span::after {
  position: absolute;
  content: "✓";
  padding-left: 5px;

运行的结果可以说明:

  • 只有 12:00 和 18:00 之间的时间才会被视为有效,超出这个范围的时间将被表示为无效。
  • 根据你使用的浏览器,你可能会发现指定范围之外的时间甚至无法在时间选择器中选择(例如 Edge)。
  • 使最小值和最大值跨越午夜

    如果设置的 min 属性大于 max 属性,有效时间范围将环绕午夜,产生一个跨越午夜的有效时间范围。这个功能不被任何其他 input 类型所支持。虽然这个功能在 HTML 规范中,但它还没有被普遍支持。基于 Chrome 的浏览器从 82 版开始支持该功能,Firefox 在 76 版中加入了该功能。Safari 从 14.1 版开始不支持这个功能。要做好出现这种情况的准备。

    js
    const input = document.createElement("input");
    input.type = "time";
    input.min = "23:00";
    input.max = "01:00";
    input.value = "23:59";
    if (input.validity.valid && input.type === "time") {
      // <input type=time> reversed range supported
    } else {
      // <input type=time> reversed range unsupported
        

    使时间成为必需值

    此外,你可以使用 required 属性来强制填写时间。因此,如果你试图提交一个超出设定范围的时间,或一个空的时间字段,支持的浏览器将显示一个错误。

    让我们看一个例子;在这里,我们设置了最小和最大的时间,也使这个字段成为必需的:

    html
    <form>
        <label for="appt-time">
          选择约定的时间(开放时间为 12:00 到 18:00):
        </label>
        <input
          id="appt-time"
          type="time"
          name="appt-time"
          min="12:00"
          max="18:00"
          required />
        <span class="validity"></span>
        <input type="submit" value="提交表单" />
    </form>
    

    如果你试图提交含有不完整的时间(或用超出设定范围的时间)的表单,浏览器会显示一个错误。现在试一试下面这个例子。

    HTML 表单验证并不能替代确保输入数据格式正确的脚本。很容易对 HTML 进行调整,使他们能够绕过验证,或完全删除验证。也有可能会完全绕过 HTML 代码,直接将数据提交给你的服务器。如果你的服务器端代码不能验证它所收到的数据,那么当提交的数据格式不当(或数据过大、类型错误等等)时,灾难就会降临。

    处理浏览器支持

    如前所述,老版本的 Safari 和其他一些不太常见的浏览器并不支持时间输入。总的来说,除此之外,支持情况良好——特别是在移动平台上,这些平台往往有非常好的用户界面来指定时间值。例如,安卓版 Chrome 浏览器上的 time 选择器看起来是这样的:

    不支持时间输入的浏览器会优雅地降级为文本输入,但这在用户界面的一致性(呈现的控件会有所不同)和数据处理方面都会产生问题。

    第二个问题更为严重;如前所述,time 输入的值总是被规范为 hh:mmhh:mm:ss 的格式。另一方面,对于文本输入,默认情况下,浏览器不知道时间应该是什么格式,而且人们有多种写法,如:

  • 3.00 pm
  • 3:00pm
  • 15:00
  • 3 o'clock in the afternoon
  • 一个办法是在你的 time 输入上添加 pattern 属性。即使 time 输入不使用它,text 输入回退也会使用。例如,试着在一个不支持时间输入的浏览器中查看下面的演示:

    html
    <form>
        <label for="appt-time">
          选择约定的时间(开放时间为 12:00 到 18:00):
        </label>
        <input
          id="appt-time"
          type="time"
          name="appt-time"
          min="12:00"
          max="18:00"
          required
          pattern="[0-9]{2}:[0-9]{2}" />
        <span class="validity"></span>
        <input type="submit" value="提交表单" />
    </form>
    

    如果你尝试提交,你会发现,如果你的输入不符合模式 nn:nn(其中 n 是 0 到 9 的数字),不支持的浏览器现在会显示一个错误信息(并突出显示输入无效)。当然,这并不能阻止人们输入无效的时间,或者不正确的遵循时间格式的时间。

    然后还有一个问题,就是用户不知道到底应该输入什么格式的时间。