> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/man1/date.1.md).

# date.1

`date` — 显示或设置日期和时间

## 名称

`date`

## 概要

`date [-nRu] [-z output_zone] [-I[FMT]] [-r filename] [-r seconds] [-v [+|-]val[y|m|w|d|H|M|S]] [+output_fmt]`

`date [-jnRu] [-z output_zone] [-I[FMT]] [-v [+|-]val[y|m|w|d|H|M|S]] [[[[cc]yy]mm]dd]HH[MM[.SS]] [+output_fmt]`

`date [-jnRu] [-z output_zone] [-I[FMT]] [-v [+|-]val[y|m|w|d|H|M|S]] -f input_fmt new_date [+output_fmt]`

## 描述

不带参数调用时，`date` 实用程序显示当前日期和时间。否则，根据指定的选项，`date` 会设置日期和时间，或以用户自定义的方式打印。

`date` 实用程序显示从内核时钟读取的日期和时间。当用于设置日期和时间时，内核时钟和硬件时钟都会更新。

只有超级用户可以设置日期，并且如果系统安全级别（参见 securelevel(7)）大于 1，则时间更改不能超过 1 秒。

选项如下：

**`-f`** `input_fmt` 使用 `input_fmt` 作为格式字符串来解析提供的 `new_date`，而不是使用默认的 `[[[[cc]yy]mm]dd]HH[MM[.SS]]` 格式。解析使用 strptime(3) 完成。

**`-I`**\[`FMT`] 使用扩展的 ISO 8601 输出格式。`FMT` 可以省略，此时默认为 `date`。有效的 `FMT` 值为 `date`、`hours`、`minutes`、`seconds` 和 `ns`（纳秒）。日期和时间格式化为指定的精度。当 `FMT` 为 `hours`（或更精确的 `minutes`、`seconds` 或 `ns`）时，扩展的 ISO 8601 格式包含时区偏移量。

**`-j`** 不尝试设置日期。这允许你将 `-f` 标志与 `+` 选项结合使用，将一种日期格式转换为另一种。请注意，`-f` 格式字符串未指定的任何日期或时间分量都取自当前时间。

**`-n`** 已废弃的标志，为兼容性而接受并忽略。

**`-R`** 使用 RFC 2822 日期和时间输出格式。这等同于在 `LC_TIME` 设置为“C”区域时，使用 `%a, %d %b %Y %T %z` 作为 `output_fmt`。

**`-r`** `seconds` 打印由 `seconds` 表示的日期和时间，其中 `seconds` 是自 Unix 纪元（1970 年 1 月 1 日 00:00:00 UTC；参见 time(3)）以来的秒数，可以用十进制、八进制或十六进制指定。

**`-r`** `filename` 打印 `filename` 最后一次修改的日期和时间。

**`-u`** 以 UTC（协调世界时）显示或设置日期。默认情况下，`date` 显示 **/etc/localtime** 或 `TZ` 环境变量所描述时区的时间。

**`-z`** `output_zone` 在打印时间之前，切换到指定的时区；参见下文对 `TZ` 的描述。这可以与 `-j` 结合使用，方便地将时间规格从一个时区转换到另一个时区。

**`-v`** \[`+`|`-`]`val` \[`y`|`m`|`w`|`d`|`H`|`M`|`S`] 根据 `val` 调整（即取当前日期并显示调整后的结果；不实际设置日期）秒、分、时、月中的日、周中的日、月或年。如果 `val` 前面有加号或减号，日期根据剩余字符串向前或向后调整，否则设置日期的相关部分。可以使用这些标志根据需要多次调整日期。标志按给定顺序处理。设置值（而非调整值）时，秒的范围是 0-59，分的范围是 0-59，小时的范围是 0-23，月中的日的范围是 1-31，周中的日的范围是 0-6（周日到周六），月的范围是 1-12（一月到十二月），年的范围则根据平台有所不同。在 i386 上，年的范围是 69-38，表示 1969-2038。在所有其他平台上，0-68 被接受并表示 2000-2068，69-99 被接受并表示 1969-1999。在两种情况下，100 到 1900（含）之间的年份被接受并解释为相对于格里高利历 1900 年，在 i386 上限制为 138，在其他平台上限制要高得多。从 1901 开始的年份也被接受，并解释为绝对年份。如果 `val` 是数字，必须使用 `y`、`m`、`w`、`d`、`H`、`M` 或 `S` 之一来指定要调整日期的哪一部分。周中的日或月可以使用名称而非数字指定。如果名称与加号（或减号）一起使用，日期将向前（或向后）调整到与给定周中的日或月匹配的下一个（或上一个）日期。如果给定的周中的日或月与当前相同，则不调整日期。当日期被调整为特定值或以大于小时的单位调整时，夏令时考虑被忽略。以小时或更小单位的调整遵守夏令时。因此，假设当前日期是 3 月 26 日 0:30，且夏令时调整意味着时钟在 01:00 前进到 02:00，使用 `-v` +1H 会将日期调整为 3 月 26 日 2:30。同样，如果日期是 10 月 29 日 0:30，且夏令时调整意味着时钟在 02:00 回退到 01:00，使用 `-v` +3H 才能到达 10 月 29 日 2:30。当日期被调整为实际上不存在的特定值（例如欧洲/伦敦时区中 2000 年 3 月 26 日 1:30 BST），日期将以一小时为单位静默向前调整，直到到达有效时间。当日期被调整为出现两次的特定值（例如 2000 年 10 月 29 日 1:30），结果时区将设置为使日期匹配两个时间中较早的一个。无法将日期调整为无效的绝对日，因此使用开关 `-v` 31d `-v` 12m 在一年中有五个月会失败。因此通常先设置月再设置日；使用 `-v` 12m `-v` 31d 总是有效的。按月调整日期本身就有歧义，因为月是一个长度可变的单位，取决于当前日期。这种日期调整以最直观的方式应用。首先，`date` 尝试保留月中的日。如果由于目标月比当前月短而无法保留，则结果为目标月的最后一天。例如，在 5 月 31 日使用 `-v` +1m 会将日期调整为 6 月 30 日，而在 1 月 30 日使用相同选项会将日期调整为 2 月的最后一天。这种方法也被认为对 shell 脚本编写最有意义。不过，请注意，前进和后退相同月数可能会带你到不同的日期。有关更多细节，请参见下面的实例。

以加号（“+”）开头的操作数指定一个用户自定义的格式字符串，用于指定显示日期和时间的格式。格式字符串可以包含 strftime(3) 手册页中描述的任何转换说明，以及任意文本。

支持对常规 strftime(3) 语法的以下扩展：

**`%`**`n``N` 替换为自 Unix 纪元以来秒数的小数部分，取 `n` 位数字。如果 `n` 省略或为零，使用默认值 9，结果是纳秒精度的数字（因此为此转换选择字母“N”）。请注意，底层时钟不一定支持纳秒精度。

**`%-N`** 同上，但根据底层时钟报告的精度自动选择精度。如果指定了 `-r` 选项，则使用默认的 9 位精度。

在格式字符串指定的字符之后，总是会输出一个换行符（`\n`）。默认显示的格式字符串为“%+”。

如果操作数不以加号开头，则被解释为用于设置系统当前日期和时间概念的值。设置日期和时间的规范表示为：

**`cc`** 世纪（19 或 20），前置于缩写年份之前。

**`yy`** 缩写形式的年份（例如 89 表示 1989，06 表示 2006）。

**`mm`** 数字月份，1 到 12 的数字。

**`dd`** 日，1 到 31 的数字。

**`HH`** 小时，0 到 23 的数字。

**`MM`** 分钟，0 到 59 的数字。

**`SS`** 秒，0 到 60 的数字（59 加上可能的闰秒）。

除分钟外，其他均为可选。

`date` 理解位于 **/usr/share/zoneinfo** 中的 IANA 时区数据库 **tzdata** 的时区定义。夏令时、标准时间、闰秒和闰年的时间更改会自动处理。

有两种指定时区的方式：

如果文件或符号链接 **/etc/localtime** 存在，它被解释为时区定义文件，通常位于目录层次结构 **/usr/share/zoneinfo** 中，其中包含来自 **tzdata** 的时区定义。

如果设置了环境变量 `TZ`，其值被解释为时区定义文件的名称，可以是绝对路径，也可以是相对于 **/usr/share/zoneinfo** 中时区定义的相对路径。`TZ` 变量覆盖 **/etc/localtime**。

如果时区定义文件无效，`date` 静默回退到 UTC。

早期版本的 `date` 包含 `-d`（设置夏令时标志）和 `-t`（设置负时区偏移）选项，但这些细节现在由 **tzdata** 自动处理。现代偏移量对于 UTC 之前的时区为正，对于 UTC 之后的时区为负，但与已废弃的 `-t` 选项类似，**/usr/share/zoneinfo/Etc** 子目录中的 **tzdata** 文件仍使用较早的约定，即 UTC 之前的时间被视为负值。

## 环境变量

以下环境变量影响 `date` 的执行：

**`TZ`** 显示日期时使用的时区。常规格式是相对于 **/usr/share/zoneinfo** 的路径名。例如，命令“TZ=America/Los\_Angeles date”显示加利福尼亚的当前时间。该变量也可以指定绝对路径。更多信息请参见 [environ(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/environ.7.md)。

## 文件

**/etc/localtime** 默认系统时区的时区信息文件。可以省略，此时默认时区为 UTC。

**/usr/share/zoneinfo** 包含时区信息文件的目录。

**/var/log/messages** 用户设置时间的记录。

**/var/log/utx.log** 日期重置和时间更改的记录。

## 退出状态

`date` 实用程序成功时退出值为 0，无法设置日期时为 1，能够设置本地日期但无法全局设置时为 2。

## 实例

命令

```sh
date +%s.%3N
```

将以毫秒精度打印自 Unix 纪元以来经过的时间。

命令：

```sh
date +DATE: %Y-%m-%d%nTIME: %H:%M:%S
```

将显示：

```sh
DATE: 1987-11-21
TIME: 13:36:16
```

在欧洲/伦敦时区，命令：

```sh
date -v1m -v+1y
```

将显示：

```sh
Sun Jan 4 04:15:24 GMT 1998
```

而当前时间是 `Mon Aug 4 04:15:24 BST 1997`。

命令：

```sh
date -v1d -v3m -v0y -v-1d
```

将显示 2000 年 2 月的最后一天：

```sh
Tue Feb 29 03:18:00 GMT 2000
```

命令：

```sh
date -v3m -v30d -v0y -v-1m
```

也会显示同样的结果，因为 2 月没有 30 日。

命令：

```sh
date -v1d -v+1m -v-1d -v-fri
```

将显示该月最后一个星期五：

```sh
Fri Aug 29 04:31:11 BST 1997
```

而当前时间是 `Mon Aug 4 04:31:11 BST 1997`。

命令：

```sh
date 8506131627
```

将日期设置为 `June 13, 1985, 4:27 PM`。

```sh
date +%Y%m%d%H%M.%S
```

可以用于在一台机器上打印出适合在另一台机器上设置的日期。（在 Linux 上与 GNU date 一起使用 `+%m%d%H%M%Y.%S`。）

命令：

```sh
date 1432
```

将时间设置为 `2:32 PM`，不修改日期。

命令

```sh
TZ=America/Los_Angeles date -Iseconds -r 1533415339
```

将显示

```sh
2018-08-04T13:42:19-07:00
```

命令：

```sh
env LC_ALL=C date -j -f %a %b %d %T %Z %Y `env LC_ALL=C date` +%s
```

可用于解析 `date` 的输出并以纪元时间表示。

最后，命令

```sh
TZ=America/Los_Angeles date -z Europe/Paris -j 0900
```

将在“America/Los\_Angeles”时区为 9:00 时，打印“Europe/Paris”时区的时间。

## 诊断

将 `-I` 标志与 `-R` 或输出格式（“+...”）操作数组合是无效的。如果发生这种情况，`date` 会打印：`multiple output formats specified` 并以状态 1 退出。

## 参见

locale(1), clock\_gettime(2), gettimeofday(2), getutxent(3), strftime(3), strptime(3), tzset(3), adjkerntz(8), ntpd(8), [tzsetup(8)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man8/tzsetup.8.md)

> R. Gusella, S. Zatti, "TSP: The Time Synchronization Protocol for UNIX 4.3BSD"。

> "Time Zone Database"。

## 标准

`date` 实用程序预期与 IEEE Std 1003.2 ("POSIX.2") 兼容。除 `-u` 选项外，所有选项都是对标准的扩展。

`-I` 标志选择的格式与 ISO 8601 兼容。

`%N` 纳秒转换说明是非标准扩展。它与 GNU date 的 `%N` 兼容。

## 历史

`date` 命令出现于 Version 1 AT\&T UNIX。

许多选项被添加然后又被移除，包括 `-d`（设置 DST 标志）和 `-t`（设置负时区偏移）。时区现在由与 **tzdata** 一起打包的代码处理。

`-I` 标志在 FreeBSD 12.0 中添加。

`%N` 转换说明在 FreeBSD 14.1 中添加。对 `%nN` 和 `%-N` 变体的支持在 FreeBSD 15.1 中添加。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man1/date.1.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
