时间概述
如何表示时间其实是一个比较复杂的问题,因为在地球环绕太阳旋转的24小时中,世界各地日出日落的时间是不同的,因此有划分时区(timezone)的必要,也就是把全球划分成24个不同的时区。我们可以把时间的定义理解为一个时间的值加上所在地的时区值(注意这个所在地可以精确到城市)。
在地理课上,我们学过格林威治时间(GMT),它就是 0 时区时间。但是我们在计算机中经常看到的是 UTC(Coordinated Universal Time 的简写,协调世界时,又称世界统一时间、世界标准时间、国际协调时间),UTC 是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,计算过程相当严谨精密,因此若以「世界标准时间」的角度来说,UTC比GMT来得更加精准。其误差值必须保持在0.9秒以内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。所以 UTC 的本质强调的是比GMT更为精确的世界时间标准。
如果中国当地时间是晚上8点钟整,我们可以使用以下两种表示方式:
20:00 CST
#或
12:00 UTC
这里的 CST 是 Chinse Standard Time(中国标准时间),也就是我们通常所说的北京时间了。因为中国处在 UTC+8 时区,即所谓的东 8 区,从而推断 UTC 为 12:00了。
虽然电脑中可以显示不同的时区的时间,其实电脑中只保留了一个时间值,那就是 UTC+0 的时间,想要得到不同时区的时间,只能通过设置不同的时区来获得。另外,还有一个称为夏令时 DST 概念,那是因为夏季太阳出来早,为了充分利用阳光,把时间拨快一定时间,到秋天拨慢回时间。
Linux 中两个时钟
Linux 有两个时钟,一个是 System Clock(系统时钟),另一个是 Hardware Clock(硬件时钟)。而在windows中只有一个硬件时钟。可以使用 date
和 hwclock
分别查看系统时钟和硬件时钟。
-
硬件时钟也称为实时时钟(RTC,real time clock)或 CMOS 时钟,它独立于任何软件,在电脑关机后仍然在运行,个人电脑上是依靠主板上的纽扣电池供电。
-
系统时钟:由 Linux Kernel(内核)维护,系统时钟在开机时会和硬件时钟同步,然后由计时器中断驱动。系统时钟记录的是自 1970-01-01 00:00:00经过的总秒数,它并不是一个整数,其精度是虚拟无穷的。
既然两个时钟是独自运行的,那么时间久了这两个时钟就会产生误差,相互之间存在一定的漂移。可以通过执行 date
和 hwclock
命令查看。
在CentOS 8 上已 root 登录
# date;hwclock
Wed Oct 12 10:13:12 CST 2022
2022-10-12 10:13:12.553904+08:00
# 如果在Ubuntu上以普通账号登录,使用 hwclock 不能正常使用
$ hwclock
hwclock: Cannot access the Hardware Clock via any known method.
hwclock: Use the --verbose option to see the details of our search for an access method.
$ sudo hwclock
2022-10-12 02:01:35.096325+00:00
# 需要使用 sudo hwclock 才能执行
$ date; sudo hwclock
Wed 12 Oct 2022 02:16:18 AM UTC
2022-10-12 02:16:19.301469+00:00
date --> 系统时钟
date
命令用于显示或设置系统时间和日期。其使用格式为:
date [OPTION]... [+FORMAT]
date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
如果不带参数和显示格式
# date
Wed Oct 12 10:25:21 CST 2022
可以带显示格式,例如:
# date +"%F %T"
2022-10-12 10:25:57
设置时间和日期
# 后面的格式是:月日年.秒,月日两位,年可以两位和四位
# date 121210302025.30
Fri Dec 12 10:30:30 CST 2025
# 也可以使用以下方式设置,这个看起来比较符合我们习惯
# date -s "2023-10-13 10:25:30"
Fri Oct 13 10:25:30 CST 2023
hwclock --> 硬件时钟
hwclock 是时钟的管理工具。它可以:显示硬件时钟时间;将硬件时钟设置为指定时间;根据系统时钟设置硬件时钟;根据硬件时钟设置系统时钟;补偿硬件时钟漂移;更正系统时间刻度;设置内核的时区、NTP时间刻度和epoch(仅Alpha);并根据漂移率预测未来的硬件时钟值。
使用格式为:
hwclock [function] [option...]
我们经常使用的命令演示如下:
可以使用以下命令查询硬件时钟:
# 其默认使用功能
# hwclock
2022-10-12 10:18:53.703334+08:00
可以不带 --show,这是默认的,这可以查询到机器上的本地时区的硬件时钟。
如果想要根据硬件时钟调整系统时钟,可以使用以下其中之一:
# hwclock --hctosys
# hwclock -s
想要根据系统时钟调整硬件时钟,可以使用以下其中之一:
# hwclock --systohc
# hwclock -w
如何查看和设置时区
查看时区
# ll /etc/localtime
lrwxrwxrwx. 1 root root 35 Oct 12 09:48 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai
# 而在Ubuntu中可以使用这个方式查询时区,在CentOS中没有该文件
$ cat /etc/timezone
Asia/Shanghai
在Linux中glibc提供了事先编译好的许多 timezone 文件,它们都存放在 /usr/share/zoneinfo
这个目录下,这里基本涵盖了大部分的国家和城市。
# ls -F /usr/share/zoneinfo/
Africa/ EST5EDT Jamaica PRC
America/ Etc/ Japan PST8PDT
Antarctica/ Europe/ Kwajalein right/
Arctic/ GB leapseconds ROC
Asia/ GB-Eire Libya ROK
Atlantic/ GMT MET Singapore
Australia/ GMT+0 Mexico/ Turkey
Brazil/ GMT-0 MST tzdata.zi
Canada/ GMT0 MST7MDT UCT
CET Greenwich Navajo Universal
Chile/ Hongkong NZ US/
CST6CDT HST NZ-CHAT UTC
Cuba Iceland Pacific/ WET
EET Indian/ Poland W-SU
Egypt Iran Portugal zone1970.tab
Eire iso3166.tab posix/ zone.tab
EST Israel posixrules Zulu
如果我们想要查看对应时区的当前时间,可以使用:
使用zdump命令可以在命令行上显示指定的每个区域名称的当前时间。
$ zdump china
china Wed Oct 12 02:47:12 2022 china
sam@Ubuntu22:~$ zdump hongkong
hongkong Wed Oct 12 02:47:18 2022 hongkong
zdump: warning: zone "hongkong" abbreviation "hongkong" has more than 6 characters
$ zdump hongk
hongk Wed Oct 12 02:47:37 2022 hongk
该命令在参数部分提供超过6个字符时,会出现警告。
设置时区
想要设置时区可以有以下方法:
tzselect
使用 tzselect
交互式命令,该命令在Linux低版本中也可以使用。
设置TZ环境变量的值。许多程序和命令都会使用这个变量的值。TZ的值可以有多种格式,最简单的设置方法是使用:
$ tzselect
Please identify a location so that time zone rules can be set correctly.
Please select a continent, ocean, "coord", or "TZ".
1) Africa
2) Americas
3) Antarctica
4) Asia
5) Atlantic Ocean
6) Australia
7) Europe
8) Indian Ocean
9) Pacific Ocean
10) coord - I want to use geographical coordinates.
11) TZ - I want to specify the timezone using the Posix TZ format.
#? 4
Please select a country whose clocks agree with yours.
1) Afghanistan 20) Iran 39) Palestine
2) Antarctica 21) Iraq 40) Philippines
3) Armenia 22) Israel 41) Qatar
4) Azerbaijan 23) Japan 42) Réunion
5) Bahrain 24) Jordan 43) Russia
6) Bangladesh 25) Kazakhstan 44) SaudiArabia
7) Bhutan 26) Korea (North) 45) Seychelles
8) Brunei 27) Korea (South) 46) Singapore
9) Cambodia 28) Kuwait 47) Sri Lanka
10) China 29) Kyrgyzstan 48) Syria
11) Christmas Island 30) Laos 49) Taiwan
12) Cocos (Keeling) Islands 31) Lebanon 50) Tajikistan
13) Cyprus 32) Macau 51) Thailand
14) East Timor 33) Malaysia 52) Turkmenistan
15) French Southern & Antarctic Lands 34) Mongolia 53) United Arab Emirates
16) Georgia 35) Myanmar (Burma) 54) Uzbekistan
17) Hong Kong 36) Nepal 55) Vietnam
18) India 37) Oman 56) Yemen
19) Indonesia 38) Pakistan
#? 10
Please select one of the following timezones.
1) Beijing Time
2) Xinjiang Time, Vostok
#? 1
The following information has been given:
China
Beijing Time
Therefore TZ='Asia/Shanghai' will be used.
Selected time is now: Wed Oct 12 10:52:42 CST 2022.
Universal Time is now: Wed Oct 12 02:52:42 UTC 2022.
Is the above information OK?
1) Yes
2) No
#? 1
You can make this change permanent for yourself by appending the line
TZ='Asia/Shanghai'; export TZ
to the file '.profile' in your home directory; then log out and log in again.
Here is that TZ value again, this time on standard output so that you
can use the /usr/bin/tzselect command in shell scripts:
Asia/Shanghai
想要永久修改这个TZ环境变量的值,可以采用以下方法:把以下这行代码,添加到你的家目录 .profile
中,然后登出及再次登录。
TZ='Asia/Shanghai'; export TZ
这样,TZ变量的值会覆盖 /etc/localtime
的值。如果想要永久修改系统的时区,可以在/etc/profile
添加TZ变量的值。
timedatectl
该命令在CentOS 7 开始或者Ubuntu可用。其用于控制系统时间和日期。
使用的语法为:
$ timedatectl [OPTIONS...] {COMMAND}
# 显示默认的状态值:
$ timedatectl
Local time: Wed 2022-10-12 12:13:16 CST
Universal time: Wed 2022-10-12 04:13:16 UTC
RTC time: Wed 2022-10-12 04:13:16
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: no
NTP service: n/a
RTC in local TZ: no
先查询有哪些时区及格式,然后进行时区的设置,该命令会同时改变内存中的和文件中的值。
$ timedatectl list-timezones
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
......
$ sudo timedatectl set-timezone Asia/Shanghai
$ ll /etc/localtime
lrwxrwxrwx 1 root root 33 Oct 12 03:14 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai
也可以设置时间和日期,并可同时改变系统时间和硬件时间。
timedatectl set-time '2022-12-12 06:06:30'
可以设置是否启用 ntp
$ timedatectl
Local time: Wed 2022-10-12 15:17:24 CST
Universal time: Wed 2022-10-12 07:17:24 UTC
RTC time: Wed 2022-10-12 07:17:23
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
NTP service: inactive
RTC in local TZ: no
$ sudo timedatectl set-ntp on
$ timedatectl
Local time: Wed 2022-10-12 15:18:43 CST
Universal time: Wed 2022-10-12 07:18:43 UTC
RTC time: Wed 2022-10-12 07:18:43
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
cal 日期
# 当月
# cal
October 2022
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
、
# 当前年
$ cal -y
2022
January February March
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 1 2 3 4 5 1 2 3 4 5
2 3 4 5 6 7 8 6 7 8 9 10 11 12 6 7 8 9 10 11 12
9 10 11 12 13 14 15 13 14 15 16 17 18 19 13 14 15 16 17 18 19
16 17 18 19 20 21 22 20 21 22 23 24 25 26 20 21 22 23 24 25 26
23 24 25 26 27 28 29 27 28 27 28 29 30 31
30 31
April May June
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 1 2 3 4 5 6 7 1 2 3 4
3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11
10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18
17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25
24 25 26 27 28 29 30 29 30 31 26 27 28 29 30
July August September
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 1 2 3 4 5 6 1 2 3
3 4 5 6 7 8 9 7 8 9 10 11 12 13 4 5 6 7 8 9 10
10 11 12 13 14 15 16 14 15 16 17 18 19 20 11 12 13 14 15 16 17
17 18 19 20 21 22 23 21 22 23 24 25 26 27 18 19 20 21 22 23 24
24 25 26 27 28 29 30 28 29 30 31 25 26 27 28 29 30
31
October November December
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 1 2 3 4 5 1 2 3
2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10
9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17
16 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24
23 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31
30 31
# 指定月
$ cal 10 2035
October 2035
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
其中一个特别的日期是,有关原因请自行查询。
# cal 9 1752
September 1752
Su Mo Tu We Th Fr Sa
1 2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30