linux 主要通过 timedatectl
和 date
之类的命令来管理时间和日期。
一、timedatectl
管理时间和日期(重点在管理)
timedatectl
可用于查询与修改系统时钟的各项设置。
语法:
timedatectl [OPTIONS...] {COMMAND}
选项(OPTIONS):
选项 | 说明 |
---|---|
--no-ask-password | 在执行特权操作时不向用户索要密码。 |
--adjust-system-clock | 当使用 set-local-rtc 命令时, 若使用了此选项, 则表示根据RTC时间来更新系统时钟。 若未使用此选项,则表示根据系统时钟来更新RTC时间。 |
-H, --host= | 操作指定的远程主机。 可以仅指定一个主机名(hostname), 也可以使用 "username@hostname" 格式。 hostname 后面还可以加上容器名(以冒号分隔), 也就是形如"hostname:container" 的格式, 以表示直接连接到指定主机的指定容器内。 操作将通过SSH协议进行,以确保安全。 可以通过 machinectl -H HOST 命令列出远程主机上的所有容器名称。 |
-M, --machine= | 在本地容器内执行操作。 必须明确指定容器的名称。 |
-h, --help | 显示简短的帮助信息并退出。 |
--version | 显示简短的版本信息并退出。 |
--no-pager | 不将程序的输出内容管道(pipe)给分页程序。 |
子命令(COMMAND)
子命令 | 说明 |
---|---|
status | 默认。用于显示系统时钟与RTC的当前状态, 包括时区设置与网络时间同步服务的状态。 注意,所谓"网络时间同步服务的状态"实际上只是 systemd-timesyncd.service 服务的状态, 并不检查是否存在其他时间同步服务。 |
set-time [TIME] | 将系统时钟设为指定的时间, 并同时更新 RTC 时间。 [TIME] 是一个形如 "2012-10-30 18:17:16"的时间字符串。 |
set-timezone [TIMEZONE] | 设置系统时区,也就是更新 /etc/localtime 软连接的指向。 可以用下面的 list-timezones 命令列出所有可用时区。 如果 RTC 被设为本地时间, 此命令还会同时更新 RTC 时间。 |
list-timezones | 列出所有可用时区,每行一个。 列出的值可以用作前述 set-timezone 命令的参数。 |
set-local-rtc [BOOL] | 设为 否(no,o) 表示在 RTC 中存储 UTC 时间; 设为 真(yes,1) 表示在 RTC 中存储 CST 时间。 应该尽一切可能在 RTC 中存储 UTC 时间。 尽量不要在 RTC 中存储 CST 时间, 因为这会造成一系列麻烦, 尤其是在切换时区以及调整夏令时或冬令时的时候。 |
set-ntp [BOOL] | 是否开启网络时间同步。 设为 "yes" 则启用并启动 systemd-timesyncd.service 服务, 设为 "no" 则停止并停用它。 |
- UTC:世界协调时间,是一个时间系统。可以理解为这个地球的标准时间,基于 SI 标准的原子时间。
- CST:中央标准时间,可以指世界不同时区的地方各自的地方时。如我国通常用亚洲/上海(东八区)时区来设置我国的地方时间。
- RTC:硬件时间,也被称为实时时钟(RTC),是指计算机主板上的一个独立于操作系统的设备,它在电源关闭甚至断电情况下也能保持运行。其功能是记录当前的日期和时间。
命令示例:
$ timedatectl # 显示系统时钟与RTC当前状态,等同于 timedatectl status
Local time: 三 2024-12-11 12:10:27 CST
Universal time: 三 2024-12-11 04:10:27 UTC
RTC time: 三 2024-12-11 12:10:24
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
NTP service: active
RTC in local TZ: yes
$ timedatectl list-timezones | grep Asia # 查看亚洲 (Asia) 可用的时区
...(省略)
Asia/Shanghai
...(省略)
$ timedatectl set-timezone Asia/Shanghai # 设置系统时区为 亚洲/上海(东八区),参数来源于上一条命令
$ timedatectl set-ntp no # 关闭时间同步,如果要手动设置系统时间,则要关闭时间同步
$ timedatectl set-time '2024-12-11 14:00:00' # 设置系统日期及时间,自行通过 timedatectl 查看 Local time 的变化
$ timedatectl set-time '2024-12-11' # 设置系统的日期,此时时间默认设置为00:00:00
$ timedatectl set-time '14:00:00' # 仅设置系统的时间,日期不变
$ timedatectl set-ntp 1 # 改回开启时间同步
系统的本地时区配置文件在哪?系统的本地时区配置文件(localtime)位于 /etc/localtime ,他是指向路径为 /usr/share/zoneinfo/Region(地区名)/City(城市名)的一个软链接
$ ls -al /etc/localtime
lrwxrwxrwx 1 root root 33 10月16日 08:46 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai
通过上面的命令我们也可以了解到当前系统时区是 Asia/Shanghai ,因此,除了 timedatectl
命令设置系统时区,我们还可以通过修改软链接的方式来设置系统时区。
$ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime # 将时区设为上海
二、date 查看和设置系统时间(重点在格式)
date 可以按照指定的格式字符串来显示系统的(或者指定的或者文件修改)时间和日期,还可以使用 -s 选项或 [MMDDhhmm[[CC]YY][.ss]] 参数来设置日期和时间。
语法:
date [选项]... [+格式字符串]
date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
选项:
选项 | 说明 |
---|---|
-d, --date=字符串 | 显示由字符串指定的时间,而不是当前时间 |
--debug | 对日期的解析过程进行注解,对不规范的用法进行警告,并输出到标准错误 |
-f, --file=日期文件 | 类似 --date;对日期文件的每一行执行一次 |
-I[格式], --iso-8601[=格式] | 以 ISO 8601 格式输出日期/时间。格式="date" 时只输出日期(默认),当其为 "hours"、"minutes"、"seconds"或 "ns" 时则按照所指示的精确度显示日期和时间。示例:2006-08-14T02:34:56-06:00 |
--resolution | 输出时间戳的可用精度 例如:0.000000001 |
-R, --rfc-email | 以 RFC 5322 格式输出日期与时间。例:Mon, 14 Aug 2006 02:34:56 -0600 |
--rfc-3339=格式 | 以 RFC 3339 格式输出日期/时间。格式="date"、"seconds" 或 "ns",按照所指示的精确度显示日期和时间。例如:2006-08-14 02:34:56-06:00 |
-r, --reference=文件 | 显示指定文件的最后修改时间 |
-s, --set=字符串 | 将时间设置为字符串所描述的时间 |
-u, --utc, --universal | 按照协调世界时 (UTC) 显示或设置时间 |
--help | 显示此帮助信息并退出 |
--version | 显示版本信息并退出 |
格式字符串:
%% 一个 % 字符
%a 当前区域设置的星期几的缩写(例如:日)
%A 当前区域设置的星期几的全称(例如:星期日)
%b 当前区域设置的月份缩写(例如:1月)
%B 当前区域设置的月份全称(例如:一月)
%c 当前区域设置的日期和时间(例如:2005年03月03日 星期四 23时05分25秒)
%C 世纪(指年份的最高两位);类似 %Y,但省略最后两位数(例如:20)
%d 日(例如:01)
%D 日期;等于 %m/%d/%y
%e 日,以空格填充;等于 %_d
%F 完整的日期;等于 %+4Y-%m-%d
%g ISO 周数年的最后两位(参见 %G)
%G ISO 周数年(参见 %V);一般只和 %V 一起使用
%h 等于 %b
%H 小时 (00..23)
%I 小时 (01..12)
%j 一年中的第几日 (001..366)
%k 小时,以空格填充 ( 0..23);等于 %_H
%l 小时,以空格填充 ( 1..12);等于 %_I
%m 月 (01..12)
%M 分钟 (00..59)
%n 换行
%N 纳秒 (000000000..999999999)
%p 当前区域设置中 AM 或 PM 的等价说法("上午" 或 "下午");未知则为空
%P 类似 %p,但使用小写
%q 季度 (1..4)
%r 当前区域设置中 12 小时制钟表时间(例如:下午 11时11分04秒)
%R 24 小时制的小时和分钟;等于 %H:%M
%s 自 Epoch (1970-01-01 00:00 UTC) 以来的秒数
%S 秒 (00..60)
%t 制表符
%T 时间;等于 %H:%M:%S
%u 星期几 (1..7);1 代表星期一
%U 一年中的第几周,以周日为每周第一天 (00..53)
%V ISO 周数,以周一为每周第一天 (01..53)
%w 星期几 (0..6);0 代表星期日
%W 一年中的第几周,以周一为每周第一天 (00..53)
%x 当前区域设置的日期表示法(例如:1999年12月31日)
%X 当前区域设置的时间表示法(例如:23时13分48秒)
%y 年的最后两位 (00..99)
%Y 年
%z +hhmm 数字时区(例如:-0400)
%:z +hh:mm 数字时区(例如:-04:00)
%::z +hh:mm:ss 数字时区(例如:-04:00:00)
%:::z 数字时区,精度上有必要时加 ":"(例如:-04、+05:30)
%Z 字母时区缩写(例如:EDT)
默认情况下,date 输出的数字字段以 0 填充。以下可选的标志可以跟在 "%" 后:
- :(连字符)不填充该字段
_ :(下划线)以空格填充
0 :(数字 0)以 0 填充
+ : 以 0 填充,并且在超过四位数的未来年份之前添加 "+" 符号
^ : 如果可能,使用大写形式
# : 如果可能,使用相反的大小写
示例:显示时间
$ date # 显示当前时间
2024年 12月 11日 星期三 13:35:05 CST
$ date +%Y年%m月%d日 # 按字符串格式显示当前时间,等同于 date +%x
2024年12月11日
$ date +'%x %X' # 按字符串格式显示当前时间,因为内部有空格,可以用单引号或双引号括起来,亦可用反斜杠(\)转义,如 date +%x\ %X
2024年12月11日 14时37分54秒
$ date --date='@60' # 显示指定时间戳(以1970年1月1日8:00:00为起点的秒数)所表示的日期,60秒刚好1分钟,等同于 date -d '@60'
1970年 01月 01日 星期四 08:01:00 CST
$ date -u --date='@60' # 显示指定时间戳的 UTC 时间,这个时间戳是从1970年1月1日0:00:00为起点的,比我们设置的 CST(东八区)早8个小时。
1970年 01月 01日 星期四 00:01:00 UTC
$ date -I"minutes" # 以 ISO 8601 格式输出日期/时间,可选参数有:"date"、"hours"、"minutes"、"seconds"或 "ns"
2024-12-11T14:42+08:00
$ date --rfc-3339="ns" # 以 RFC 3339 格式输出日期/时间。后面的参数有:"date"、"seconds" 或 "ns"
2024-12-11 14:47:26.958356683+08:00
$ date -r images/Debian\ APT.png # 显示images/Debian APT.png 的最后修改时间
2023年 11月 24日 星期五 21:20:20 CST
示例:设置时间
$ date -s 2024-12-13 # 设置时间,因为我开启了时钟同步(ntp 为 1),所以设置不成功,但后面显示了假设设置成功后的时间
date: 无法设置日期: 不允许的操作
2024年 12月 13日 星期五 00:00:00 CST
$ date -s "Sun, 29 Feb 2004 16:21:42 -0800" -u # 加 -u 参数,设置 UTC 时间,字符串后面的-0800是西八区,转换为 UTC 时间要加 8 小时
date: 无法设置日期: 不允许的操作
2004年 03月 01日 星期一 00:21:42 UTC
日期字符串:--date=字符串
选项中的的字符串可以是人类易于理解阅读的日期字符串,
例如 "Sun, 29 Feb 2004 16:21:42 -0800" 或 "2004-02-29 16:21:42",甚至可以是 "next Thursday"。
一个日期字符串可能包含表示日历日期、一日中的具体时间、时区、星期、相对时间、相对日期和数字的信息。
一个空字符串表示当日的起始。日期字符串的具体格式较为复杂,其完整内容可以在 info 文档中找到。