shell脚本专家指南笔记#3.日期和时间操作

本文介绍了在Shell脚本中如何用天数计算日期,包括Unix时间戳的原理和转换,以及如何评估当前日期和时间进行任务调度。重点讨论了从1970年1月1日至今的天数计算公式,并展示了`date`命令在不同场景下的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

##
# 本文为《shell脚本专家指南》一书的学习笔记。
##

3.1. 用天数来计算日期
    unix和linux以1970年1月1日0时0分开始计算时间,也就是所谓的时间戳,单位是
        秒。在系统中,可以使用 date +'%s' 来查看。
    严格来讲,系统的起止时间是以零时区开始计算的。比如,一般我们系统的时区为
        东八区(+8),故使用 date -d '1970-1-1 0:0' +'%s'得到是-28800,即当
        东八区为1970-1-1 0:0时,零时区的时间实际为1969-12-31 16:00。
    linux中/etc/shadow文件中,第三个字段,保留了用户上次修改密码的时间,距
        1970-1-1经过的天数。
    计算公式
        (Year*365)+(Year/4)-(Year/100)+(Year/400)+(Month*306001/10000)+(Day)
        公式适用于1582-10-15到9999-12-31时间段的天数计算,数值为指定日期到
            元年的天数。
        公式套用中,1月2月中,年份要减1,月份要加13,对于非1月2月,直接月份
            加1就可以套用。据网上的说法,可能跟月份乘以的306001这个值有关系。
            据说是月的平均天数。
        关于这个公式。。。建议不要瞎想,我瞎想了两天,都没想出个头绪,最后
            看仔细作者对公式的描述,才恍然大悟。这个公式只是为了便于计算
            1582-10-15到9999-12-31范围内不同日期间的天数差值。如果单独给公式套入
            一个日期,得到的天数并没有任何意义。
        unix的纪元日期为公元纪元的1970-1-1,可以记一个固定值719591,用于快速
            计算各日期据unix纪元日期的天数。
    
    3.1.1. 自从纪元以来的天数
示例:该脚本计算的描述,为当前时区的时间,至纪元时间的秒数。
系统的 date +%s 命令,显示的为零时区至纪元时间的描述。
比如,在东八区,该脚本执行的秒数为 1544809090 ,而date +%s输出为 1544780309 。
两者相差 28781 ,刚好是7.99(两条命令分开执行,时间上差了几秒)。

#!/bin/bash
epoch_days=719591

declare -a DATE=(`date +"%S %M %H %d %m %Y"`)

year="${DATE[5]}"
month="${DATE[4]}"
day="${DATE[3]}"
hour="${DATE[2]}"
minute="${DATE[1]}"
second="${DATE[0]}"

if [ $month -gt 2 ];
then
  month=$(($month+1))
else
  month=$(($month+13))
  year=$($year-1)
fi

today_days=$(( $year*365 + $year/4 -$year/100 + $year/400 + $month*306001/10000 + $day ))
echo $today_days
days_since_epoch=$(( $today_days - $epoch_days ))
echo $days_since_epoch
seconds_since_epoch=`echo "$days_since_epoch*86400 + $hour*3600 + $minute*60 + $second" | bc`
echo $seconds_since_epoch

 

    3.1.2. 以秒计算日期的其他方法
        在gnu版本中,date 命令可以直接加参 +%s 来获取秒数,为零时区对应时间
            至纪元时间的秒数。

 

3.2. 评估当前日期和时间
    书中给出了一个示例,通过判断当前星期和小时,决定是否调度一个作业。

#!/bin/bash
test $# -ne 4 && {
  echo "Usage: $0 <day begin> <day end> <hour begin> <hour end>"
  echo "  Days are 0-6 where 0 is Sunday."
  echo "  Hours are 0-23"
  exit 9
}

DAY_BEGIN=$1
DAY_END=$2
HOUR_BEGIN=$3
HOUR_END=$4

DAY=`date +%w`
HOUR=`date +%H`

if [ $DAY -ge $DAY_BEGIN -a $DAY -le $DAY_END ] && [ $HOUR -ge $HOUR_BEGIN -a $HOUR -le $HOUR_END ];
then
  echo "It is time to notify."
  # 原文为return 0。
  exit 0
else
  echo "It is not time to notify."
  # 原文为return 1。
  exit 1
fi

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值