第一章:The Missing Code Library--7.合法化日期格式

   全部的合法化輸入腳本中,最有挑戰的一個非屬於操做日期不可。它的目的是確保一個給定的日期在現實中是存在的。若是忽略閏年,這個任務並不難,由於每一年的日期都頗有一致性。這種狀況下,咱們所要作的僅僅是將一個給定的日期和每月的天數進行比較。可是爲了計算閏年,就須要增長一些額外的邏輯了。      下面就是一個計算閏年的規則集合:
1.不能被4整除的不是閏年
2.能被4和400同時整除的是閏年
3.能被4整除,但不能被400整除,可又能被100整除的,不是閏年

4.除了上述狀況,全部能被4整除的都是閏年 shell

代碼:
函數

validdate.sh
 #!/bin/sh
 
 # validdate.sh--合法化一個日期,兼顧到閏年
 
 exceedsDaysinMonth()
 {
     # 給定一個月份,若是給定的天小於等於該月的最大天數,返回0
     # 不然,返回1
 
     case $(echo $1 | tr '[:upper:]' '[:lower:]') in
         jan* ) days=31;;  feb* ) days=28;;
         mar* ) days=31;;  apr* ) days=30;; 
         may* ) days=31;;  jun* ) days=30;; 
         jul* ) days=31;;  aug* ) days=31;; 
         sep* ) days=30;;  oct* ) days=31;; 
         nov* ) days=30;;  dec* ) days=31;;
         *) echo "$0: Unknown month name $1" >&2; exit 1
     esac
 
     if [ $2 -lt 1 -o $2 -gt $days ]; then
         return 1
     else
         return 0    # 天的數字合法
     fi
 }
 
 isLeepYear()
 {
     # 若是是閏年,函數返回0;不然,返回1
     # 判斷閏年的規則是:如上所述的4點
 
     year=$1
 
     if [ "$((year%4))" -ne 0 ]; then
         return 1 
     elif [ "$((year%400))" ]; then
         return 0
     elif [ "$((year%100))" ]; then
         return 1
     else
         return 0
     fi
 }
 
 # 開始腳本的主要部分
 
 if [ $# -ne 3 ]; then
     echo "用法: $0 月 日 年" >&2
     echo "正確的輸入格式是: August 3 1962和8 3 2002" >&2
     exit 1
 fi
 
 # 正常化日期,
 
 newdate="$(normdate.sh "$@")"
 
 if [ $? -eq 1 ]; then
     exit 1         # normdate報告的錯誤狀態
 fi
 
 month="$(echo $newdate | cut -d\  -f1)"     # 注意,-d\後面到-f1之間有2個空格,反斜線\的做用是轉義空格
   day="$(echo $newdate | cut -d\  -f2)"
  year="$(echo $newdate | cut -d\  -f3)"
 
 # 既然日期已經正常化了,那就測試下天數的值是否正確
 
 if ! exceedsDaysinMonth $month "$2"; then
     if [ "$month" = "Feb" -a "$2" -eq "29" ]; then
         if ! isLeepYear $3; then
             echo "$0: $3 不是一個閏年,因此2月沒有29天." >&2
             exit 1
         fi
     else
         echo "$0: 錯誤的天數: $month 沒有 $2 天." >&2
         exit 1
     fi
 fi
 
 echo "正確日期: $newdate"
 
 exit 0

運行腳本:
要運行腳本,只須要在命令行給出一個格式爲「月 日 年」的日期。月能夠是三個字母的縮寫、完整月份或者是數字;可是年必須是一個4位的數字。 測試

運行結果: spa

validdate.sh august 3 1960
 正確日期: Aug 3 1960
 validdate.sh 9 3 2001
 正確日期: Sep 3 2001
 validdate.sh feb 29 2004
 正確日期: Feb 29 2004
 ./validdate.sh feb 29 2006
 ./validdate.sh: 2006 不是一個閏年¸因此2月沒有29天.
分析腳本:
相似於這個腳本中的思路,咱們也能夠寫一個合法化時間的腳步。時間的表示格式有:使用24小時制;使用am/pm後綴。在冒號處切割時間的值,確保分鐘和秒數(若是有給出)在0-60之間,若是是am/pm的就再覈實下第一個值是否在0-12之間,或者是24小時制的是否在0-24之間。(幸運的是,時間中有閏秒和其它細小的變更來保持日曆的平衡,因此在平常的基礎上咱們徹底能夠忽略它們)
相關文章
相關標籤/搜索