linux 主要通过 timedatectldate 之类的命令来管理时间和日期。

一、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 文档中找到。