Linux 下date命令的常见用法

456 阅读6分钟

在写 shell 脚本的时候会经常需要比较时间,根据比较的结果执行不同的逻辑。date是Linux中日期和时间相关的命令,它主要是把时间以指定的格式展示出来,它也是最常用的命令之一

命令和语法

 date [OPTION]... [+FORMAT]

date 的输出格式比较多,下面列出一些常用的输出格式

%m : 当前是一年中第几个月,例如:七月显示 07

%d : 当前是一个月中第几天,例如:一个月中第一天显示 01

%j :当前是一年中第几天(001366)

%V : 当前是一年中第几个星期,每周第一天是周一

%U : 当前是一年中第几个星期,每周第一天是周日

%w :当前是一个星期中第几天(1-6 表示周一到周六,0 表示周日)

%z :当前所在时区,比如北京是在 +0800 时区

%s : UTC时间的秒数,从1970-01-01 00:00:00到现在经过的秒数

%Y :当前是哪一年

%M : 当前是一个小时中第几分钟

%S :当前是一分钟中第几秒

当前所在时区

[root@ecs-centos-7 tt]# date +%z
+0800

UTC时间和日期互相转换

[root@ecs-centos-7 tt]# date
Mon Jul 27 20:32:46 CST 2020
[root@ecs-centos-7 tt]# date +%s
1595853166

[root@ecs-centos-7 tt]# date -d '@1595853166' '+%F %T'
2020-07-27 20:32:46
[root@ecs-centos-7 tt]# date -d "2020-07-27 20:32:46" +%s
1595853166

上面的例子中,把当前时间转换成 UTC 的时间,也可以把指定的时间字符串转换成UTC秒数,还可以把指定的UTC秒数转换成对应的日期,由此可见UTC时间和日期之间可以互相转换的

通过时间戳转换网站把UTC的秒数:1595853166 转换成具体的日期,转换结果如下图:

例子中,当前时间是:2020-07-27 20:32:46 转化成 UTC 时间的秒数是:1595853166 ,然后再通过时间戳转换网站来验证,结果表明两者的答案是一致的

修改系统时间

只有root用户才有权限修改系统时间,所以下面的命令需要先切换到root用户执行,否则会提示没有执行权限

  • 修改全部的时间
[root@ecs-centos-7 tt]# date -s "20200727 20:42:30"
Mon Jul 27 20:42:30 CST 2020
[root@ecs-centos-7 tt]# date -s "2020-07-27 20:42:30"
Mon Jul 27 20:42:30 CST 2020
  • 只修改时间,不修改年月日
[root@ecs-centos-7 tt]# date
Mon Jul 27 20:43:23 CST 2020
[root@ecs-centos-7 tt]# date -s "20:43:00"
Mon Jul 27 20:43:00 CST 2020
[root@ecs-centos-7 tt]# date
Mon Jul 27 20:43:01 CST 2020
  • 只修改年月日
[root@ecs-centos-7 tt]# date
Mon Jul 27 20:44:51 CST 2020
[root@ecs-centos-7 tt]# date -s "2020-07-28"
Tue Jul 28 00:00:00 CST 2020
[root@ecs-centos-7 tt]# date
Tue Jul 28 00:00:00 CST 2020

[root@ecs-centos-7 tt]# date -s "20200727"
Mon Jul 27 00:00:00 CST 2020
[root@ecs-centos-7 tt]# date
Mon Jul 27 00:00:02 CST 2020

上面的例子展示了两种修改年月日的方式,需要注意的是:只修改年月日之后,时间默认变成当天的 00:00:00

时间加减

当前时间时 2020-07-27,下面的例子都是以此为基础时间的

  • 增减分钟、小时
[root@ecs-centos-7 tt]# date
Mon Jul 27 02:26:00 CST 2020
[root@ecs-centos-7 tt]# date -d '+10 min' '+%F %T'  
2020-07-27 02:36:02
[root@ecs-centos-7 tt]# date -d '-10 min' '+%F %T'   
2020-07-27 02:16:05

Mon Jul 27 02:27:21 CST 2020
[root@ecs-centos-7 tt]#  date -d '+2 hour' '+%F %T'   
2020-07-27 04:27:22
[root@ecs-centos-7 tt]#  date -d '-2 hour' '+%F %T'    
2020-07-27 00:27:26
  • 增减天数
[root@ecs-centos-7 tt]# date -d '+1 day' +%F
2020-07-28
[root@ecs-centos-7 tt]# date -d '-2 day' +%F         
2020-07-25
  • 增减星期
[root@ecs-centos-7 tt]# date -d '+1 week' +%F       
2020-08-03
[root@ecs-centos-7 tt]# date -d '-2 week' +%F     
2020-07-13
  • 增减月份
[root@ecs-centos-7 tt]# date -d '+1 month' +%F   
2020-08-27
[root@ecs-centos-7 tt]# date -d '-2 month' +%F    
2020-05-27
  • 增减年份
[root@ecs-centos-7 tt]# date -d '+1 year' +%F     
2021-07-27
[root@ecs-centos-7 tt]# date -d '-1 year' +%F    
2019-07-27

处理文件中的字符串时间

-f 选项是用来处理文件中时间字符串的,现有 a.txt ,文件内容如下:

[root@ecs-centos-7 tt]# cat a.txt 
2020-07-27 20:03:00
2020-07-26 20:04:00
2020-07-25 20:05:00

把文件中每一行的时间转化成UTC时间,输出如下:

[root@ecs-centos-7 tt]# date -f a.txt +%s
1595851380
1595765040
1595678700

脚本中计算时间差

通常在shell脚本中需要计算出两个时间变量的差值, 我们可以通过把时间字符串转化成 UTC 的秒数来计算时间差,下面是 test.sh 的脚本内容

#!/bin/bash

starttime=`date +%s`
echo "process logic..."
sleep 5s
endtime=`date +%s`
diff=$((endtime - starttime))
echo "starttime:${starttime}, endtime:${endtime}, diff:"${diff}

上面是一段简单的测试脚本,脚本开始记录当前时间,然后用睡眠5秒来表示执行逻辑花费了5秒,逻辑执行完后,再次记录下结束时间,打印出开始、结束以及时间差

执行 ./test.sh,输出如下:

[root@ecs-centos-7 ~]# ./test.sh 
process logic...
starttime:1595790297, endtime:1595790302, diff:5

上面的输出中,结束时间和开始时间差是5秒,表示脚本执行花费的时间是5秒,跟测试中结果一致