第二章:Improving On User Commands--22.顯示不一樣時區的時間

   一個日期命令最基本的需求就是顯示你所在時區的日期和時間。可是若是你有用戶是跨時區的呢?或者,若是你有朋友或是同事時在不一樣的地區呢?你就會一直搞不清楚那兒如今究竟是個什麼日子了,好比卡薩布蘭卡、梵蒂岡或是悉尼。 git

   如今大部分的Unix系統都有一個date命令,它的後臺是一個時區數據庫。它的位置通常是在目錄/usr/share/zoneinfo下,它列出了超過250個不一樣的地區,而且能夠明確表示出各個不一樣地區的時間。由於date命令注重的是時間變量TZ,該變量能夠被設置爲不一樣的已知地區,那麼核心的功能能夠經過以下表示:
TZ="Africa/Casablanca" date
   經過一個shell腳本,咱們能夠建立一個對用戶界面友好的時區數據庫:要知道,大部分系統用戶並不喜歡臨時設置環境變量 shell

代碼: 數據庫

#!/bin/sh
 
 # timein.sh -- 顯示特定時區或是地區的時間.
 # 若是沒有提供任何參數,就顯示 UTC/GMT.
 # 使用單詞"list"來查看已知地區列表
 # 注意:有可能匹配到地區,但只有時區是合法的。
 
 # 時區數據庫網址: http://www.twinsun.com/tz/tz-link.htm
 
 zonedir="/usr/share/zoneinfo"
 
 if [ ! -d $zonedir ]; then
     echo "No time zone database at $zonedir." >&2
     exit 1
 fi
 
 if [ -d "$zonedir/posix" ]; then
     zonedir=$zonedir/posix  # 現代Linux系統
 fi
 
 if [ $# -eq 0 ]; then
     timezone="UTC"
     mixedzone="UTC"
 elif [ "$1" = "list" ]; then
     (echo "All known time zones and regions defined on this system:"
     cd $zonedir
     find * -type f -print | xargs -n 2 | \
     awk '{printf "%-38s %-38s\n", $1, $2}'    
     ) | more
     exit 0
 else
     region="$(dirname $1)"  # 若是參數格式是 Asia/Beijing,那region是Asia
     zone="$(basename $1)"   # 若是參數格式是 Beijing,那region就是個點
 
     # 剛好能夠匹配?很是好。不然咱們須要探索一番。
     # 從計算匹配的個數開始。
 
     matchcnt="$(find $zonedir/$region -name $zone -type f -print |
         wc -l | sed 's/[^[:digit:]]//g')"  #上面的查找路徑,應該加上$region,不然查找的不精確。書中沒有。
                                            #好比給出形如 Asia/Beijing 的參數,若是路徑中沒有Asia,那永遠也查不到北京
 
     if [ "$matchcnt" -gt 0 ]; then  # 至少一個文件匹配
         if [ "$matchcnt" -gt 1 ]; then  # 超過一個文件匹配
             echo "\"$zone\" matches more than one possible time zone record." >&2
             echo "Please use 'list' to see all known regions and time zones." >&2
             exit 1
         fi
         match="$(find $zonedir -name $zone -type f -print)"
         mixedzone="$zone"
     else
         # 第一個字母大寫,其他單詞小寫: region + zone
         mixedregion="$(echo ${region%${region#?}} | tr '[[:lower:]]' '[[:upper:]]')\
 $(echo ${region#?} | tr '[[:upper:]]' '[[:lower:]]')"  #行頭千萬別留下空格或者製表符
         mixedzone="$(echo ${zone%${zone#?}} | tr '[[:lower:]]' '[[:upper:]]')\
 $(echo ${zone#?} | tr '[[:upper:]]' '[[:lower:]]')"    #行頭千萬別留下空格或者製表符
 
         if [ "$mixedregion" != "." ]; then
             # 只查特定地方
             # 當有多種可能性時,讓用戶指定惟一匹配項(好比"Atlantic")
             match="$(find $zonedir/$mixedregion -name $mixedzone -type f -print)"
         else
             match="$(find $zonedir -name $mixedzone -type f -print)"
         fi
 
         if [ -z "$match" ]; then
             if [ ! -z "$(find $zonedir -name $mixedzone -type d -print)" ]; then
                 echo \
                 "The region \"$1\" has more than one time zone. Please use 'list'" >&2
             else  # 沒有一個匹配
                 echo "Can't find an exact match for \"$1\". Please use 'list'" >&2
             fi
             echo "to see all known regions and time zones." >&2
             exit 1
         fi
     fi
     timezone="$match"
 fi
 
 nicetz=$(echo $timezone | sed "s|$zonedir/||g")
 
 echo It\'s $(TZ=$timezone date '+%A, %B %e, %Y, at %l:%M %p') in $nicetz
 
 exit 0

腳本如何工做:
    這個腳本利用的就是date命令來顯示日期和時間。事實上,這整個腳本關注的就是要確認好你給的時區名,這樣在腳本的最後才能如期運行好。
這個腳本最複雜的地方來自預測由用戶輸入的,不匹配時區數據庫中的任一個名字的地區名。時區數據庫會按照時區名按地區列排好,在有典型的輸入問題時,腳本也會試圖報有用的錯誤信息。
    好比,雖然TZ="Casablanca"並不嫩成功的查找到一個匹配的地區,而date命令會演示GMT,城市Casablanca確實是存在於地區數據庫中的。可能的名字,Africa/Casablanca,就會被提供給這個腳本。腳本會找到非洲目錄下的卡薩布蘭卡,而後正確的確認這個地區。指定"Africa",從另外一面來講,腳本知道有分區,只提供那些信息不足以惟一指定一個時區。
最後,你一樣可使用一個時區名(好比,UTC、WET)做爲腳本參數來查看定義好的時區的子集。
   注意,一個很是棒的時區數據庫的參考資料在線:http://www.twinsun.com/tz/tz-link.htm this

注:UTC是協調世界時(Universal Time Coordinated)英文縮寫,北京時間比UTC時間早8小時。GMT(Greenwich Mean Time)是格林尼治平時。 code

運行腳本: htm

./timein.sh 
 It's 星期一, 十二月 24, 2012, at 12:19 上午 in UTC
 
 ./timein.sh London
 It's 星期一, 十二月 24, 2012, at 12:19 上午 in Europe/London
 
 ./timein.sh Brazil
 The region "Brazil" has more than one time zone. Please use 'list'
 to see all known regions and time zones.
 
 ./timein.sh Pacific/Honolulu
 It's 星期日, 十二月 23, 2012, at 2:21 下午 in Pacific/Honolulu
 
 ./timein.sh WET
 It's 星期一, 十二月 24, 2012, at 12:21 上午 in WET
 
 ./timein.sh mycloset
 Can't find an exact match for "mycloset". Please use 'list'
 to see all known regions and time zones.
相關文章
相關標籤/搜索