• shell 脚本中日期运算


    平常写shell脚本的过程中,经常要用到日期的运算,比如:日期的加减、与UTC时间换算,比较大小等等,下面就来聊一聊这些常用的日期运算

    日期加减

    • 秒增减
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "70 second 2020-10-20 12:00:00"
    2020-10-20 12:01:10
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "-70 second 2020-10-20 12:00:00"
    2020-10-20 11:58:50
    
    • 分钟增减
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "10 minute 2020-10-20 12:00:00"
    2020-10-20 12:10:00
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "-10 minute 2020-10-20 12:00:00"
    2020-10-20 11:50:00
    
    • 小时增减
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "1 hour 2020-10-20 12:00:00"
    2020-10-20 13:00:00
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "-1 hour 2020-10-20 12:00:00"
    2020-10-20 11:00:00
    
    • 天增减
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "3 day 2020-10-20 12:00:00"
    2020-10-23 12:00:00
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "-3 day 2020-10-20 12:00:00"
    2020-10-17 12:00:00
    
    • 周增减
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "1 week 2020-10-20 12:00:00"
    2020-10-27 12:00:00
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "-1 week 2020-10-20 12:00:00"
    2020-10-13 12:00:00
    
    • 月增减
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "2 month 2020-10-20 12:00:00"
    2020-12-20 12:00:00
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "-2 month 2020-10-20 12:00:00"
    2020-08-20 12:00:00
    
    • 年增减
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "1 year 2020-10-20 12:00:00"
    2021-10-20 12:00:00
    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "-1 year 2020-10-20 12:00:00"
    2019-10-20 12:00:00
    
    • 年月日时分秒增减

    年月日时分秒除了每一个单独进行日期增减之外,还可以一起使用

    [root@ecs-centos-7 ~]# date +'%Y-%m-%d %H:%M:%S' -d "1 year 2 month 1 week 3 hour -10 minute 40 second 2020-10-20 12:00:00"
    2021-12-27 14:50:40
    
    
    • 一个月中第几天
    [root@ecs-centos-7 ~]# date +%Y%m%d
    20201023
    [root@ecs-centos-7 ~]# date +%d
    23
    [root@ecs-centos-7 ~]# date +%d -d "20201013"
    13
    

    date +%d 命令是计算当前日期( 2020年10月23日 ) 是一个月中的第几天

    date +%d -d "20201013" 命令是计算 2020年10月13日 是一个月中第几天

    • 一年中第几周
    [root@ecs-centos-7 ~]# date +%Y%m%d
    20201023
    [root@ecs-centos-7 ~]# date +%V
    43
    [root@ecs-centos-7 ~]# date +%V -d "20201005"
    41
    

    上面例子中, date +%V 命令是计算当前日期是一年中第几周,星期一是一周的第一天,取值范围是 01-53,date +%V -d "20201005" 命令是计算指定日期 ( 20201005 ) 是一年中第几周

    • 一周中第几天
    [root@ecs-centos-7 ~]# date +%Y%m%d
    20201023
    [root@ecs-centos-7 ~]# date +%u
    5
    [root@ecs-centos-7 ~]# date +%u -d "20201004"
    7
    

    上面的例子中,date +%u 命令是计算当前日期是一周中第几天,取值范围是 1 - 7,分别表示周一至周日,结果是 5,表示当前这一天是周五, date +%u -d "20201004" 命令是计算指定日期 ( 20201004 ) 是一周中第几天,结果是 7 ,表示 2020年10月4日是周日

    [root@ecs-centos-7 ~]# date +%Y%m%d
    20201023
    [root@ecs-centos-7 ~]# date +%w
    5
    [root@ecs-centos-7 ~]# date +%w -d "20201004"
    0
    

    上面例子中,date +%w 命令是也是计算当前日期是一周中第几天,取值范围是 0 - 6 , 0 代表周日,1 - 6 分别代表周一至周六

    命令 date +%w -d "20201004" 是计算指定日期 ( 20201004 ) 是一周中第几天,结果是 0,表示2020年10月4日是周日

    月第一天和月最后一天

    [root@ecs-centos-7 ~]# date +"%Y-%m-%d"  -d  "-$(($(date +%d -d '2020-10-20') -1 )) days  2020-10-20"
    2020-10-01
    
    [root@ecs-centos-7 ~]# date +"%Y-%m-%d"  -d  "-$(($(date +%d -d '2020-10-20') )) days +1 month  2020-10-20"
    2020-10-31
    
    

    上面例子中,date +"%Y-%m-%d" -d "-$(($(date +%d -d '2020-10-20') -1 )) days 2020-10-20" 命令是计算日期 2020-10-20 中月份的第一天, 结果是 2020-10-01

    命令 date +"%Y-%m-%d" -d "-$(($(date +%d -d '2020-10-20') )) days +1 month 2020-10-20" 是计算日期 2020-10-20 中月份的最后一天, 结果是 2020-10-31

    日期和UTC时间互相转换

    • 日期转 UTC 时间

    UTC时间是整数,把日期转成UTC时间,更方便各种计算

    [root@ecs-centos-7 ~]# date +%s
    1603443806
    [root@ecs-centos-7 ~]# date +%s -d "2020-10-20 12:00:00"
    1603166400
    [root@ecs-centos-7 ~]# date +%s -d "2020-10-20 00:00:00"
    1603123200
    [root@ecs-centos-7 ~]# date +%s -d "2020-10-20"
    1603123200
    [root@ecs-centos-7 ~]# date +%s -d "2020-10-01"
    1601481600
    

    上面例子中,date +%s 命令是把当前时间转成 UTC 时间,date +%s -d "2020-10-20 12:00:00" 命令是把 2020-10-20 12:00:00 转成UTC时间

    • UTC时间转日期
    [root@ecs-centos-7 ~]# date +%s -d "2020-10-20 12:00:00"
    1603166400
    [root@ecs-centos-7 ~]# date -d "@1603166400"
    2020年 10月 20日 星期二 12:00:00 CST
    

    命令 date +%s -d "2020-10-20 12:00:00" 是计算 2020-10-20 12:00:00 的UTC时间,这里主要是为了和后面UTC时间转日期做对比用的

    命令 date -d "@1603166400" 是计算UTC时间( 1603166400 ) 对应的日期,计算结果是 2020年 10月 20日 星期二 12:00:00 CST 前一条命令的日期参数是一致的

    日期比较大小

    shell中直接比较日期相当于字符串比较,可以先把日期转成UTC时间再进行比较,下面是一个日期比较的测试脚本 ( t.sh ),执行时需要传入两个待比较的日期

    #!/bin/bash
    
    date1=$(date +%s -d "$1")
    date2=$(date +%s -d "$2")
    
    if [[ ${date1} -lt ${date2} ]]; then
    	echo " $1  <  $2 "
    elif [[ ${date1} -eq ${date2} ]]; then
    	echo " $1  =  $2 "
    else
    	echo " $1  >  $2 "
    fi
    

    执行测试脚本,具体结果如下:

    [root@localhost shell_test]# ./t.sh "20201020" "20201020"
     20201020  =  20201020 
    [root@localhost shell_test]# ./t.sh "20201020" "20201021"
     20201020  <  20201021 
    [root@localhost shell_test]# ./t.sh "20201020" "20201019"
     20201020  >  20201019 
     [root@localhost shell_test]# 
     
    [root@localhost shell_test]# ./t.sh "2020-10-20 00:00:01" "2020-10-20 00:00:00"
     2020-10-20 00:00:01  >  2020-10-20 00:00:00 
    [root@localhost shell_test]# ./t.sh "2020-10-20 00:00:01" "2020-10-20 00:00:01"
     2020-10-20 00:00:01  =  2020-10-20 00:00:01 
    [root@localhost shell_test]# ./t.sh "2020-10-20 00:00:01" "2020-10-20 00:00:10"
     2020-10-20 00:00:01  <  2020-10-20 00:00:10 
    [root@localhost shell_test]# 
    

    从结果可以看出, t.sh 脚本传入日期参数既可以只有年月日又可以年月日时分秒都有,而且日期的格式既可以是 20201020 格式,又可以是 2020-10-20 00:00:00 格式的

    日期循环遍历

    在工作中,经常要处理一段时间内的日志,需要遍历日期,然后对每天的日志做处理,下面的测试脚本 ( t.sh ) 是测试日期遍历的, 脚本内容如下:

    #!/bin/bash
    
    
    #开始日期
    begindate=$1
    #结束日期
    enddate=$2
    
    #后一天日期,用于循环
    nextdate=${begindate}
    #后一天日期的utc时间,用于比较日期
    nextutc=$(date +%s -d "${nextdate}")
    #结束日期的UTC时间
    endutc=$(date +%s -d "${enddate}")
    
    
    while [ ${nextutc} -le ${endutc} ]
    do
    	echo "process ${nextdate} log..."
    	#计算后一天的日期
    	nextdate=$(date -d "${nextdate} 1 day" +%Y%m%d)
    	#计算后一天日期的utc时间
    	nextutc=$(date +%s -d "${nextdate}")
    	
    done
    

    执行测试脚本,具体结果如下:

    [root@localhost shell_test]# ./t.sh "20201020" "20201023"
    process 20201020 log...
    process 20201021 log...
    process 20201022 log...
    process 20201023 log...
    
  • 相关阅读:
    使用vscode 用git 拉取代码,提示:在签出前,请清理存储库工作树
    区分手机端和pc端加载不同的样式
    关于vue的代码规范
    各种名词汇总整理
    ZB埋点汇总
    项目实战 OLAP数据提取
    大数据intern_1总结:数据埋点以及SQL复习
    leetcode 343+279+91+64+70 动态规划
    leetcode 241 加优先级括号
    leetcode 17+79+93+46+47+77+39+40+78+90+131+37 回溯法
  • 原文地址:https://www.cnblogs.com/wanng/p/14105935.html
Copyright © 2020-2023  润新知