HTML 中使用的日期和时间格式

某些 HTML 元素使用日期和/或时间值。本文描述了指定这些值的字符串的格式。

¥Certain HTML elements use date and/or time values. The formats of the strings that specify these values are described in this article.

使用此类格式的元素包括允许用户选择或指定日期、时间或两者的某些形式的 <input> 元素,以及 <ins><del> 元素,其 datetime 属性指定插入的日期或日期和时间 或发生内容删除。

¥Elements that use such formats include certain forms of the <input> element that let the user choose or specify a date, time, or both, as well as the <ins> and <del> elements, whose datetime attribute specifies the date or date and time at which the insertion or deletion of content occurred.

对于 <input>,返回包含表示日期和/或时间的字符串的 valuetype 的值是:

¥For <input>, the values of type that return a value which contains a string representing a date and/or time are:

示例

¥Examples

在深入了解如何在 HTML 中编写和解析日期和时间字符串的复杂性之前,这里有一些示例,可以让你很好地了解更常用的日期和时间字符串格式。

¥Before getting into the intricacies of how date and time strings are written and parsed in HTML, here are some examples that should give you a good idea what the more commonly-used date and time string formats look like.

Example HTML date and time strings
字符串 日期和/或时间
XSPACE2005-06-07 2005 年 6 月 7 日 [细节]
XSPACE08:45 8:45 AM [细节]
XSPACE08:45:25 上午 8:45 25 秒 [细节]
XSPACE0033-08-04T03:40 33 年 8 月 4 日凌晨 3:40 [细节]
XSPACE1977-04-01T14:00:30 1977 年 4 月 1 日下午 2:00 后 30 秒 [细节]
XSPACE1901-01-01T00:00Z 1901 年 1 月 1 日午夜(世界标准时间) [细节]
XSPACE1901-01-01T00:00:01-04:00 1901 年 1 月 1 日东部标准时间 (EST) 午夜过后 1 秒 [细节]

基本

¥Basics

在查看 HTML 元素使用的各种格式的日期和时间相关字符串之前,了解有关它们定义方式的一些基本事实会很有帮助。HTML 使用 ISO 8601 标准的变体来表示其日期和时间字符串。值得检查你所使用的格式的描述,以确保你的字符串实际上与 HTML 兼容,因为 HTML 规范包含用于解析这些字符串的算法,该算法实际上比 ISO 8601 更精确,因此可能存在微妙的差异 日期和时间字符串预期外观的差异。

¥Before looking at the various formats of date and time related strings used by HTML elements, it is helpful to understand a few fundamental facts about the way they're defined. HTML uses a variation of the ISO 8601 standard for its date and time strings. It's worth reviewing the descriptions of the formats you're using in order to ensure that your strings are in fact compatible with HTML, as the HTML specification includes algorithms for parsing these strings that is actually more precise than ISO 8601, so there can be subtle differences in how date and time strings are expected to look.

字符集

¥Character set

HTML 中的日期和时间始终是使用 ASCII 字符集的字符串。

¥Dates and times in HTML are always strings which use the ASCII character set.

年份数字

¥Year numbers

为了简化 HTML 中日期字符串使用的基本格式,该规范要求使用现代(或易推论)公历 给出所有年份。虽然用户界面可能允许使用其他日历输入日期,但基础值始终使用公历。

¥In order to simplify the basic format used for date strings in HTML, the specification requires that all years be given using the modern (or proleptic) Gregorian calendar. While user interfaces may allow entry of dates using other calendars, the underlying value always uses the Gregorian calendar.

虽然公历直到 1582 年才创建(取代类似的儒略历),但出于 HTML 的目的,公历可追溯到公元 1 年。确保所有较早的日期都考虑到了这一点。

¥While the Gregorian calendar wasn't created until the year 1582 (replacing the similar Julian calendar), for HTML's purposes, the Gregorian calendar is extended back to the year 1 C.E. Make sure any older dates account for this.

就 HTML 日期而言,年份始终至少为四位数字;1000 年之前的年份用前导零(“0”)填充,因此 72 年写为 0072。公元 1 年之前的年份不受支持,因此 HTML 不支持公元前 1 年。(公元前 1 年)或更早。

¥For the purposes of HTML dates, years are always at least four digits long; years prior to the year 1000 are padded with leading zeroes ("0"), so the year 72 is written as 0072. Years prior to the year 1 C.E. are not supported, so HTML doesn't support years 1 B.C.E. (1 B.C.) or earlier.

一年通常有 365 天,闰年 期间除外。

¥A year is normally 365 days long, except during leap years.

闰年

¥Leap years

闰年是指任何能被 400 整除的年份,或者能被 4 但不能被 100 整除的年份。虽然日历年通常有 365 天,但实际上地球绕太阳运行一周大约需要 365.2422 天。闰年有助于调整日历,使其与行星在其轨道上的实际位置保持同步。每四年在一年中增加一天,实质上使一年的平均长度为 365.25 天,这接近正确的值。

¥A leap year is any year which is divisible by 400 or the year is divisible by 4 but not by 100. Although the calendar year is normally 365 days long, it actually takes the planet Earth approximately 365.2422 days to complete a single orbit around the sun. Leap years help to adjust the calendar to keep it synchronized with the actual position of the planet in its orbit. Adding a day to the year every four years essentially makes the average year 365.25 days long, which is close to correct.

对算法的调整(当年份可被 400 整除时采用闰年,当年份可被 100 整除时跳过闰年)有助于使平均值更接近正确的天数(365.2425 天)。科学家偶尔会在日历中(认真地)添加闰秒,以处理一天中剩余的万分之三,并补偿地球自转逐渐、自然发生的减慢。

¥The adjustments to the algorithm (taking a leap year when the year can be divided by 400, and skipping leap years when the year is divisible by 100) help to bring the average even closer to the correct number of days (365.2425 days). Scientists occasionally add leap seconds to the calendar (seriously) to handle the remaining three ten-thousandths of a day and to compensate for the gradual, naturally occurring slowing of Earth's rotation.

2 月 02 月通常有 28 天,但闰年有 29 天。

¥While month 02, February, normally has 28 days, it has 29 days in leap years.

一年中的几个月

¥Months of the year

一年有 12 个月,编号为 1 至 12。它们始终由两位 ASCII 字符串表示,其值范围为 0112。请参阅第 每月的天数 节中的表格了解月份编号及其相应名称(以及以天为单位的长度)。

¥There are 12 months in the year, numbered 1 through 12. They are always represented by a two-digit ASCII string whose value ranges from 01 through 12. See the table in the section Days of the month for the month numbers and their corresponding names (and lengths in days).

每月的天数

¥Days of the month

月份数字 1、3、5、7、8、10 和 12 的长度为 31 天。第 4、6、9 和 11 个月共 30 天。第 2 个月,即二月,大多数年份有 28 天,但闰年有 29 天。下表对此进行了详细说明。

¥Month numbers 1, 3, 5, 7, 8, 10, and 12 are 31 days long. Months 4, 6, 9, and 11 are 30 days long. Month 2, February, is 28 days long most years, but is 29 days long in leap years. This is detailed in the following table.

The months of the year and their lengths in days
月份数 名称(英文) 长度(以天为单位)
01 一月 31
02 二月 28(闰年为 29)
03 行进 31
04 四月 30
05 可能 31
06 六月 30
07 七月 31
08 八月 31
09 九月 30
10 十月 31
11 十一月 30
12 十二月 31

周弦

¥Week strings

周字符串指定特定年份中的一周。有效的周字符串由有效的 年号、后跟连字符(“-”或 U+002D)、大写字母“W”(U+0057) 和两位数的年份周值组成 。

¥A week string specifies a week within a particular year. A valid week string consists of a valid year number, followed by a hyphen character ("-", or U+002D), then the capital letter "W" (U+0057), followed by a two-digit week of the year value.

一年中的第几周是 0153 之间的两位数字符串。每周从星期一开始,到星期日结束。这意味着一月的前几天可能被视为上一周年的一部分,而十二月的最后几天可能被视为下一周年的一部分。一年中的第一周是包含一年中第一个星期四的一周。例如,1953 年的第一个星期四是 1 月 1 日,因此从 12 月 29 日星期一开始的那一周被视为一年中的第一周。因此,1952 年 12 月 30 日发生在 1953-W01 周内。

¥The week of the year is a two-digit string between 01 and 53. Each week begins on Monday and ends on Sunday. That means it's possible for the first few days of January to be considered part of the previous week-year, and for the last few days of December to be considered part of the following week-year. The first week of the year is the week that contains the first Thursday of the year. For example, the first Thursday of 1953 was on January 1, so that week—beginning on Monday, December 29—is considered the first week of the year. Therefore, December 30, 1952 occurs during the week 1953-W01.

一年有 53 周,如果:

¥A year has 53 weeks if:

  • 日历年的第一天(1 月 1 日)是星期四或
  • 一年的第一天(1 月 1 日)是星期三,年份是 闰年

所有其他年份都有 52 周。

¥All other years have 52 weeks.

周字符串 周和年(日期范围)
2001-W37 2001 年第 37 周(2001 年 9 月 10 日至 16 日)
1953-W01 1953 年第 1 周(1952 年 12 月 29 日至 1953 年 1 月 4 日)
1948-W53 1948 年第 53 周(1948 年 12 月 27 日至 1949 年 1 月 2 日)
1949-W01 1949 年第 1 周(1949 年 1 月 3 日至 9 日)
0531-W16 第 16 周, 531 (4 月 13-19, 531)
0042-W04 42 年第 4 周(42 年 1 月 21 日至 27 日)

请注意,年份和周数都用前导零填充,其中年份填充为四位数,周填充为两位数。

¥Note that both the year and week numbers are padded with leading zeroes, with the year padded to four digits and the week to two.

月份字符串

¥Month strings

月份字符串表示时间上的特定月份,而不是一年中的通用月份。也就是说,HTML 月份字符串不是表示 "一月,",而是表示配对的月份和年份,如 "1972 年 1 月。"

¥A month string represents a specific month in time, rather than a generic month of the year. That is, rather than representing "January," an HTML month string represents a month and year paired, like "January 1972."

有效的月份字符串包含有效的 年号(至少四位数字的字符串),后跟连字符(“-”或 U+002D),后跟两位数字 月份数,其中 01 代表一月,12 代表十二月。

¥A valid month string consists of a valid year number (a string of at least four digits), followed by a hyphen character ("-", or U+002D), followed by a two-digit numeric month number, where 01 represents January and 12 represents December.

月份字符串 月份和年份
17310-09 17310 年 9 月
2019-01 2019 年 1 月
1993-11 1993 年 11 月
0571-04 571 年 4 月
0001-07 公元 1 年 7 月

请注意,所有年份的长度至少为四个字符;长度少于四位数的年份用前导零填充。

¥Notice that all years are at least four characters long; years that are fewer than four digits long are padded with leading zeroes.

日期字符串

¥Date strings

有效的日期字符串由 月份字符串、后跟连字符(“-”或 U+002D)和两位数 该月的某一天 组成。

¥A valid date string consists of a month string, followed by a hyphen character ("-", or U+002D), followed by a two-digit day of the month.

日期字符串 完整日期
1993-11-01 1993 年 11 月 1 日
1066-10-14 1066 年 10 月 14 日
0571-04-22 571 年 4 月 22 日
0062-02-05 62 年 2 月 5 日

时间字符串

¥Time strings

时间字符串可以指定精确到分钟、秒或毫秒的时间。不允许仅指定小时或分钟。有效的时间字符串至少包含两位数的小时,后跟冒号(“:”,U+003A),然后是两位数的分钟。分钟后可以选择跟另一个冒号和两位数的秒数。可以选择通过添加小数点字符(“.”、U+002E)后跟一位、两位或三位数字来指定毫秒。

¥A time string can specify a time with precision to the minute, second, or to the millisecond. Specifying only the hour or minute isn't permitted. A valid time string minimally consists of a two-digit hour followed by a colon (":", U+003A), then a two-digit minute. The minute may optionally be followed by another colon and a two-digit number of seconds. Milliseconds may be specified, optionally, by adding a decimal point character (".", U+002E) followed by one, two, or three digits.

还有一些额外的基本规则:

¥There are some additional basic rules:

  • 时间始终使用 24 小时制指定,00 为午夜,晚上 11 点为 23。不允许使用超出 0023 范围的值。
  • 分钟必须是 0059 之间的两位数。不允许超出该范围的值。
  • 如果省略秒数(以指定仅精确到分钟的时间),则分钟数后面不应有冒号。
  • 如果指定,秒数的整数部分必须介于 0059 之间。你不能使用 6061 等值指定闰秒。
  • 如果指定秒数并且是整数,则后面不能跟小数点。
  • 如果包含秒的一小部分,则其长度可能为一到三位数,表示毫秒数。它位于时间字符串的秒部分后面的小数点之后。
时间字符串 时间
00:00:30.75 12:00:30.75 AM(午夜后 30.75 秒)
12:15 12:15 PM
13:44:25 下午 1:44:25(下午 1:44 后 25 秒)

本地日期和时间字符串

¥Local date and time strings

有效的 datetime-local 字符串由 date 字符串和 time 字符串连接在一起,并用字母“T”或空格字符分隔它们。字符串中不包含有关时区的信息;日期和时间被假定为用户的本地时区。

¥A valid datetime-local string consists of a date string and a time string concatenated together with either the letter "T" or a space character separating them. No information about the time zone is included in the string; the date and time is presumed to be in the user's local time zone.

当你设置 datetime-local 输入的 value 时,字符串将被标准化为标准形式。规范化的 datetime 字符串始终使用字母“T”来分隔日期和时间,并且字符串的时间部分尽可能短。这是通过省略秒部分(如果其值为 :00)来完成的。

¥When you set the value of a datetime-local input, the string is normalized into a standard form. Normalized datetime strings always use the letter "T" to separate the date and the time, and the time portion of the string is as short as possible. This is done by leaving out the seconds component if its value is :00.

Examples of valid datetime-local strings
日期/时间字符串 标准化日期/时间字符串 实际日期和时间
XSPACE1986-01-28T11:38:00.01 XSPACE1986-01-28T11:38:00.01 1986 年 1 月 28 日上午 11:38:00.01
XSPACE1986-01-28 11:38:00.010

XSPACE1986-01-28T11:38:00.01

请注意,标准化后,该字符串与之前的 datetime-local 字符串相同。空格已替换为 "T" 字符,并且删除了不到一秒的尾随零,以使字符串尽可能短。

1986 年 1 月 28 日上午 11:38:00.01
XSPACE0170-07-31T22:00:00

XSPACE0170-07-31T22:00

请注意,此日期的规范化形式将指示秒数的 ":00" 删除为零,因为秒在零时是可选的,并且规范化字符串最小化了字符串的长度。

170 年 7 月 31 日晚上 10:00

全局日期和时间字符串

¥Global date and time strings

全局日期和时间字符串指定日期和时间及其发生的时区。有效的全局日期和时间字符串与 本地日期和时间字符串 的格式相同,只是它在时间后面附加了一个时区字符串。

¥A global date and time string specifies a date and time as well as the time zone in which it occurs. A valid global date and time string is the same format as a local date and time string, except it has a time zone string appended to the end, following the time.

时区偏移字符串

¥Time zone offset string

时区偏移字符串指定与标准时基的正数或负数小时数和分钟数的偏移量。有两个标准时基,它们非常接近相同,但不完全相同:

¥A time zone offset string specifies the offset in either a positive or a negative number of hours and minutes from the standard time base. There are two standard time bases, which are very close to the same, but not exactly the same:

  • 对于 1960 年代初建立 协调世界时 (UTC) 后的日期,时基为 Z,偏移量表示特定时区相对于经度 0° 的本初子午线(经过英国格林威治皇家天文台)时间的偏移量 )。
  • 对于 UTC 之前的日期,时基以 UT1 表示,即本初子午线处的当代地球太阳时。

时区字符串紧跟在日期和时间字符串中的时间后面。你可以指定“Z”作为时区偏移字符串,以指示时间以 UTC 格式指定。否则,时区字符串的构造如下:

¥The time zone string is appended immediately following the time in the date and time string. You can specify "Z" as the time zone offset string to indicate that the time is specified in UTC. Otherwise, the time zone string is constructed as follows:

  1. 指示偏移量符号的字符:加号字符(“+”或 U+002B)表示本初子午线以东的时区,减号字符(“-”或 U+002D)表示本初子午线以西的时区。
  2. 时区偏离本初子午线的两位数小时数。该值必须在 0023 之间。
  3. 可选的冒号(“:”)字符。
  4. 整点过去的两位数分钟数;该值必须在 0059 之间。

虽然此格式允许 -23:59 和 +23:59 之间的时区,但时区偏移的当前范围是 -12:00 到 +14:00,并且当前没有时区与小时的偏移量除了 003045 分钟。这可能随时发生或多或少的改变,因为各国可以随时以任何他们希望的方式自由地篡改其时区。

¥While this format allows for time zones between -23:59 and +23:59, the current range of time zone offsets is -12:00 to +14:00, and no time zones are currently offset from the hour by anything other than 00, 30, or 45 minutes. This may change at more or less anytime, since countries are free to tamper with their time zones at any time and in any way they wish to do so.

Examples of valid global date and time strings
全局日期和时间字符串 实际的全球日期和时间 本初子午线的日期和时间
XSPACE2005-06-07T00:00Z 世界标准时间 2005 年 6 月 7 日午夜 2005 年 6 月 7 日午夜
XSPACE1789-08-22T12:30:00.1-04:00 1789 年 8 月 22 日中午 12:30 十分之一秒东部夏令时间 (EDT) 1789 年 8 月 22 日下午 4:30 十分之一秒
XSPACE3755-01-01 00:00+10:00 3755 年 1 月 1 日午夜澳大利亚东部标准时间 (AEST) 3754 年 12 月 31 日下午 2:00

日期问题

¥Date issues

由于数据存储和精度问题,你可能需要了解一些客户端和服务器端问题。

¥Because of data storage and precision issues, you may want to be aware of a few client-side and server-side issues.

Y2K38 问题(通常是服务器端)

¥The Y2K38 Problem (often server-side)

JavaScript 使用双精度浮点来存储日期,就像所有数字一样,这意味着 JavaScript 代码不会遇到 Y2K38 问题,除非使用整数强制/位黑客,因为所有 JavaScript 位运算符都使用 32 位有符号 2s 补码整数。

¥JavaScript uses double precision floating points to store dates, as with all numbers, meaning that JavaScript code will not suffer from the Y2K38 problem unless integer coercion/bit-hacks are used because all JavaScript bit operators use 32-bit signed 2s-complement integers.

问题出在服务器端:存储大于 2^31 的日期 - 1.如果你的服务器是用 PHP 编写的,则修复可能很简单,只需升级到 PHP 8 或 7,并将硬件升级到 x86_64 或 IA64 即可。如果你遇到其他硬件问题,可以尝试在 32 位虚拟机中模拟 64 位硬件,但大多数虚拟机不支持这种虚拟化,因为稳定性可能会受到影响,性能肯定会受到很大影响。

¥The problem is with the server side of things: storage of dates greater than 2^31 - 1. To fix this problem, you must store all dates using either unsigned 32-bit integers, signed 64-bit integers, or double-precision floating points on the server. If your server is written in PHP, the fix may be as simple as upgrading to PHP 8 or 7, and upgrading your hardware to x86_64 or IA64. If you are stuck with other hardware, you can try to emulate 64-bit hardware inside a 32-bit virtual machine, but most VMs don't support this kind of virtualization, since stability may suffer, and performance will definitely suffer greatly.

万年问题(通常是客户端)

¥The Y10k Problem (often client-side)

在许多服务器中,日期存储为数字而不是字符串 - 数字具有固定大小且与格式无关(除了字节序)。10,000 年之后,这些数字只会比以前大一点,因此许多服务器不会发现 10,000 年之后提交的表单出现问题。

¥In many servers, dates are stored as numbers instead of as strings--numbers of a fixed size and agnostic of format (aside from endianness). After the year 10,000, those numbers will just be a bit bigger than before, so many servers will not see issues with forms submitted after the year 10,000.

问题出在客户端:解析年份中超过 4 位数字的日期。

¥The problem is with the client side of things: parsing of dates with more than 4 digits in the year.

html
<!--midnight of January 1st, 10000: the exact time of Y10K-->
<input type="datetime-local" value="+010000-01-01T05:00" />

就是这么简单。只需准备任意位数的代码即可。不要只准备 5 位数。以下是用于以编程方式设置值的 JavaScript 代码:

¥It's that simple. Just prepare your code for any number of digits. Do not only prepare for 5 digits. Here is JavaScript code for programmatically setting the value:

js
function setValue(element, date) {
  const isoString = date.toISOString();
  element.value = isoString.substring(0, isoString.indexOf("T") + 6);
}

如果万年问题会在你死后几个世纪才会发生,为什么要担心它呢?正是因为你已经死了,所以使用你的软件的公司将陷入使用你的软件的困境,而没有任何其他足够了解系统的编码人员介入并修复它。

¥Why worry about the Y10K problem if it is going to happen many centuries after your death? Exactly because you will already be dead, so the companies using your software will be stuck using your software without any other coder who knows the system well enough to come in and fix it.

也可以看看

¥See also