本文将介绍linux中date命令的使用和技巧,列举了如参数、输出、设置、转换、时间戳等,示例并对注意点进行了说明。
本文也介绍了系统时间和硬件时间的区别,另外,对于time命令也进行了简单的说明。
date -help亦可查看。
Linux系统里自带的一个系统命令,可以以给定的格式显示当前时间,或是设置系统日期。
在date命令中,默认显示的结果里包括很多信息,特别是做为文件名输出时,不是很方便,但好在里包含格式化输出的选项:
date [OPTION]... [+FORMAT]
date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
如果命令没有带任何参数时,则默认显示系统当期时间,输出时间为:格林威治时间,并把日期和时间按CST格式输出。
-d, --date=STRING
显示由 STRING 指定的时间, 而不是当前时间
-f, --file=DATEFILE
显示 DATEFILE 中每一行指定的时间, 如同将 DATEFILE 中的每行作为 --date 的参数一样
-I[FMT], --iso-8601[=FMT]
按照 ISO-8601 的日期/时间格式输出时间.
FMT=`date' (或者不指定时)仅输出日期,等于 `hours', `minutes', 或`seconds' 时按照指定精度输出日期及时间.
-r, --reference=FILE
显示 FILE 的最后修改时间
-R, --rfc-822
根据 RFC-822 指定格式输出日期
-s, --set=STRING
根据 STRING 设置时间
-u, --utc, --universal
显示或设置全球时间(格林威治时间)
--help
显示本帮助文件并退出
--version
显示版本信息并退出
格式 FORMAT 控制着输出格式. 仅当选项指定为全球时间时本格式才有效。 分别解释如下:
%% 文本的 %
%a 当前区域的星期几的简写 (Sun..Sat)
%A 当前区域的星期几的全称 (不同长度) (Sunday..Saturday)
%b 当前区域的月份的简写 (Jan..Dec)
%B 当前区域的月份的全称(变长) (January..December)
%c 当前区域的日期和时间 (Sat Nov 04 12:02:33 EST 1989)
%d (月份中的)几号(用两位表示) (01..31)
%D 日期(按照 月/日期/年 格式显示) (mm/dd/yy)
%e (月份中的)几号(去零表示) ( 1..31)
%h 同 %b
%H 小时(按 24 小时制显示,用两位表示) (00..23)
%I 小时(按 12 小时制显示,用两位表示) (01..12)
%j (一年中的)第几天(用三位表示) (001..366)
%k 小时(按 24 小时制显示,去零显示) ( 0..23)
%l 小时(按 12 小时制显示,去零表示) ( 1..12)
%m 月份(用两位表示) (01..12)
%M 分钟数(用两位表示) (00..59)
%n 换行
%N 纳秒 (000000000..999999999)
%p 当前时间是上午 AM 还是下午 PM
%r 时间,按 12 小时制显示 (hh:mm:ss [A/P]M)
%s 从 1970年1月1日0点0分0秒到现在历经的秒数 (GNU扩充)
%S 秒数(用两位表示)(00..60)
%t 水平方向的 tab 制表符
%T 时间,按 24 小时制显示(hh:mm:ss)
%U (一年中的)第几个星期,以星期天作为一周的开始(用两位表示) (00..53)
%V (一年中的)第几个星期,以星期一作为一周的开始(用两位表示) (01..52)
%w 用数字表示星期几 (0..6); 0 代表星期天
%W (一年中的)第几个星期,以星期一作为一周的开始(用两位表示) (00..53)
%x 按照 (mm/dd/yy) 格式显示当前日期
%X 按照 (%H:%M:%S) 格式显示当前时间
%y 年的后两位数字 (00..99)
%Y 年(用 4 位表示) (1970...)
%z 按照 RFC-822 中指定的数字时区显示(如, -0500) (为非标准扩充)
%Z 时区(例如, EDT (美国东部时区)), 如果不能决定是哪个时区则为空
默认情况下,日期的数字区域以0 填充,比如2020年02月16日会表示成2020-02-16。
以下可选标记可以跟在"%"后:
- (连字符) 不填充该域
_ (下划线) 以空格填充
0 (数字0)以0 填充
^ 如果可能,使用大写字母
# 如果可能,使用相反的大小写
在任何标记之后还允许一个可选的域宽度指定,它是一个十进制数字。
作为一个可选的修饰声明,它可以是E,在可能的情况下使用本地环境关联的
表示方式;或者是O,在可能的情况下使用本地环境关联的数字符号。
#默认显示,等同于:date -u 。 Sun Feb 16 18:33:00 CST 2020
date
#输出指定格式: YYYY/MM/DD hh:mm:ss.zzzzzzzzz 2020/02/16 18:36:57.324679800
date '+%Y/%m/%d %H:%M:%S.%N'
# 输出完整日期和时间,等同于 “ %Y-%m-%d %H:%M:%S” 2020-02-17 18:46:55
date "+%F %T"
注意1:若是 不以 加号作为开头,则表示要设定时间,而时间格式为 MMDDhhmm[[CC]YY][.ss]。其中 MM 为月份,DD 为日,hh 为小时,mm 为分钟,CC 为年份前两位数字,YY 为年份后两位数字,ss 为秒数。
注意2:当不希望出现无意义的 0 时(比如说 1999/03/07),则可以在标记中插入 - 符号。比如说 date '+%-H:%-M:%-S' 会把时分秒中无意义的 0 给去掉,像是原本的 08:09:04 会变为 8:9:4。
#设置完整的时间
date -s "2020-02-16 18:24:34"
date -s "18:24:34 2020-02-16"
#设置日期,由于没有设置时间,所以时间都是00:00:00
date -s "2020-02-17"
date -s "20200216"
#设置具体时间,不会对日期做更改
date -s "01:01:01"
注意:设置时间时,不支持毫秒、微秒、纳秒的设置,只支持秒级别。
需使用:-d 参数,可将指定的时间字符串,按照指定的格式输出(并不会改动系统时间)。
# 转换指定日期为Unix时间戳:
date -d “'2020-02-16 18:35:05' +%s"
Unix时间戳转换为日期时间:
date -d "@1581849305" "+%Y-%m-%d %H:%M:%S"
注意1:秒点时,参数前面一定要带上 @ 参数。
注意2:数据转换照样只支持秒点级别以上的计算。
Unix时间戳(英文为Unix epoch, Unix time, POSIXme 或 Unix timestamp),是指从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。
date 命令可以直接把当前时间转化为时间戳,方法:date "+%s" 。带上 -d 参数,还可以实现指定日期和秒点之间的转换。
date 命令亦可以获取当前时间的纳秒,方法:date "+%N"。
如此,我们就可以进行相应的计算,得到对于的微秒、毫秒和纳秒数。
#当前系统时间转换为时间戳
date "+%s"
#当前系统时间纳秒数
date "+%s"
#当前系统时间纳秒点
date "+%s%N"
#当前系统时间微秒点
expr $(date "+%s%N") / 1000
#当前系统时间毫秒点
expr $(date "+%s%N") / 1000000
借助 -d 或是 --date 参数,。或是先将指定的时间转换为秒点,再用 expr 命令 对其计算。
date -d last-day "+%F %T"
date -d yesterday "+%F %T"
date -d next-month "+%F %T"
date -d next-year "+%F %T"
date -d "5 days ago" "+%F %T"
date -d week "+%F %T"
date -d "Nov 12 - 2 days" "+%F %T"
date -d "12/12 - 2 days" "+%F %T"
date -d "2 days" "+%F %T"
date -d "-1day" +%F
date -d "+2hour 2min 2sec" +%F\ %H:%M:%S
常用的时区取值有:
所以相关计算时候,一定要特别注意,是否加上UTC时间秒点:8 * 60 * 60 = 28,800。
date默认输出时,使用的本地时间,即CST:Sun Feb 16 18:26:58 CST 2020。
如果需要查看当前时区时间,带上 -R 参数: date -R :Sun, 16 Feb 2020 18:27:12 +0800
linux系统时钟有两个,一个是硬件时钟(Real Time Clock),叫RTC,即BIOS时间,就是我们进行CMOS设置时看到的时间。另一个是系统时钟(System clock),也叫内核时钟或者软件时钟,是linux系统Kernel时间。
当Linux启动时,系统Kernel会去读取硬件时钟的设置,然后系统时钟就会独立于硬件运作,是由软件根据时间中断来进行计数的,内核时钟在系统关机的情况下是不存在的。并且在系统关机的时,会将系统时间写回RTC中进行同步。
所以,为了保持系统时间与CMOS时间的一致性,Linux每隔一段时间会将系统时间写入CMOS。
由于该同步是每隔一段时间(大约是11分钟)进行的,在我们执行date -s后,如果马上重起机器,修改时间就有可能没有被写入CMOS,这就是问题的原因。如果要确保修改生效可以执行命令: clock –w。这个命令强制把系统时间写入CMOS。
#查看硬件时间
hwclock --show
clock --show
#设置硬件时间
hwclock --set --date="2020-02-17 18:30:00"
clock --set --date="2020-02-17 18:30:00"
#同步时间到shell
hwclock
#同步互联网时间
ntpdate time.windows.com
#硬件时钟与系统时钟同步(hc代表硬件时间,sys代表系统时间):
hwclock --hctosys
clock --hctosys
#系统时钟和硬件时钟同步:
hwclock --systohc
clock --systohc
常用于测量一个指令执行时所需消耗的时间及系统资源等资讯,例如 CPU 时间、记忆体、输入输出等等。
所以这里不再多讲。
注意1:本命令不是用来显示和修改系统时间的(这是date命令干的事情)。
注意2:部分资讯在 Linux 上会显示不出来。这是因为在 Linux 上部分资源的分配函式与 time 指令所预设的方式并不相同,以致于 time 指令无法取得这些资料。