当前位置 博文首页 > anyuzun的博客:shell脚本专家指南笔记#3.日期和时间操作
##
# 本文为《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
?
cs