1. 程式人生 > >shell指令碼專家指南筆記#3.日期和時間操作

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