<!DOCTYPE html>

Bash中关于日期时间操作的常用自定义函数

Bash中关于日期时间操作的常用自定义函数
Thursday, July 3, 2014
5:13 PM

在编写Linux Bash脚本时,经常会用到一些日期时间有关的命令,下面是我多年Shell编程中常用的函数,现在整理出来,希望起到抛砖引玉的作用。

 

 

附件包括三个文件:

datetime.sh  包含了Bash中关于日期时间操作的常用自定义函数

test_datetime.sh 用来展示datetime.sh中自定义函数的用法

test_datetime.txt 是test_datetime.sh的一次执行输出样本

 

执行命令:

Bash代码  

  1. ./test_datetime.sh >test_datetime.txt  

 

 

文件:datetime.sh

Bash代码  

  1. #!/bin/sh  
  2.   
  3.   
  4. # Copyright (c) 2010 codingstandards. All rights reserved.  
  5. # file: datetime.sh  
  6. # description: Bash中关于日期时间操作的常用自定义函数  
  7. # license: LGPL  
  8. # author: codingstandards  
  9. # version: 1.0  
  10. # date: 2010.02.27  
  11.   
  12.   
  13. # usage: yesterday  
  14. 昨天  
  15. 比如今天是2010227日,那么结果就是2010-02-26  
  16. yesterday()  
  17. {  
  18.     date --date='1 day ago' +%Y-%m-%d  
  19. }  
  20.   
  21. # usage: today  
  22. 今天  
  23. 比如今天是2010227日,那么结果就是2010-02-27  
  24. today()  
  25. {  
  26.     date +%Y-%m-%d  
  27. }  
  28.   
  29. # usage: now  
  30. 现在,包括日期和时间、纳秒  
  31. 比如:2010-02-27 11:29:52.991774000  
  32. now()  
  33. {  
  34.     date "+%Y-%m-%d %H:%M:%S.%N"  
  35. }  
  36.   
  37. # usage: curtime  
  38. 当前时间,包括日期和时间  
  39. 比如:2010-02-27 11:51:04  
  40. curtime()  
  41. {  
  42.     date '+%Y-%m-%d %H:%M:%S'  
  43.     # 也可写成:date '+%F %T'  
  44. }  
  45.   
  46. # usage: last_month  
  47. 取上个月的年月  
  48. 比如:2010-01  
  49. last_month()  
  50. {  
  51.     date --date='1 month ago' '+%Y-%m'  
  52. }  
  53.   
  54. # usage: last_month_packed  
  55. 取上个月的年月  
  56. 比如:201001  
  57. last_month_packed()  
  58. {  
  59.     date --date='1 month ago' '+%Y%m'  
  60. }  
  61.   
  62. # usage: first_date_of_last_month  
  63. 取上个月的第一天  
  64. 比如本月是20102月,那么结果就是2010-01-01  
  65. first_date_of_last_month()  
  66. {  
  67.     date --date='1 month ago' '+%Y-%m-01'  
  68. }  
  69.   
  70. # usage: last_date_of_last_month  
  71. 取上个月的最后一天  
  72. 比如当前是20102月,那么结果就是2010-01-31  
  73. last_date_of_last_month()  
  74. {  
  75.     date --date="$(date +%e) days ago" '+%Y-%m-%d'  
  76. }  
  77.   
  78. # usage: day_of_week  
  79. 今天的星期  
  80. # day of week (0..6);  0 represents Sunday  
  81. day_of_week()  
  82. {  
  83.     date +%w  
  84. }  
  85.   
  86. # usage: last_hour  
  87. 上个小时  
  88. 比如:2010-02-27-10  
  89. 适合处理log4j生成的日志文件名  
  90. last_hour()  
  91. {  
  92.     date --date='1 hour ago' +%Y-%m-%d-%H  
  93. }  
  94.   
  95. # usage: the_hour  
  96. 当前的小时,为方便算术比较,结果不以0开头  
  97. 比如:12  
  98. the_hour()  
  99. {  
  100.     #date +%H   # hour (00..23)  
  101.     date +%k    # hour ( 0..23)  
  102. }  
  103.   
  104. # usage: the_minute  
  105. 当前的分钟,为方便算术比较,结果不以0开头  
  106. 比如:  
  107. the_minute()  
  108. {  
  109.     MM=$(date +%M)  # minute (00..59)  
  110.     echo $[1$MM-100]  
  111. }  
  112.   
  113. # usage: the_second  
  114. 当前的秒数  
  115. 比如:  
  116. the_second()  
  117. {  
  118.     SS=$(date +%S)  # second (00..60); the 60 is necessary to accommodate a leap  second  
  119.     echo $[1$SS-100]  
  120. }  
  121.   
  122. # usage: the_year  
  123. 当前的年份 year (1970...)  
  124. 比如:2010  
  125. the_year()  
  126. {  
  127.     date +%Y  
  128. }  
  129.   
  130. # usage: the_month  
  131. 当前的月份,为方便算术比较,结果不以0开头  
  132. 比如:2  
  133. the_month()  
  134. {  
  135.     M=$(date +%m) # month (01..12)  
  136.     echo $[1$M-100]  
  137. }  
  138.   
  139. # usage: the_date  
  140. 当前的日期,为方便算术比较,结果不以0开头  
  141. 比如:27  
  142. the_date()  
  143. {  
  144.     date +%e    # day of month, blank padded ( 1..31)  
  145. }  
  146.   
  147. # usage: days_ago <n>  
  148. n天前的日期  
  149. 比如:days_ago 0就是今天,days_ago 1就是昨天,days_ago 2就是前天,days_ago -1就是明天  
  150. 格式:2010-02-27  
  151. days_ago()  
  152. {  
  153.     date --date="$1 days ago" +%Y-%m-%d  
  154. }  
  155.   
  156. # usage: chinese_date_and_week()  
  157. 打印中文的日期和星期  
  158. 比如:227 星期六  
  159. chinese_date_and_week()  
  160. {  
  161.     WEEKDAYS=(星期日 星期一 星期二 星期三 星期四 星期五 星期六)  
  162.     WEEKDAY=$(date +%w)  
  163.     #DT="$(date +%Y%m%d) ${WEEKDAYS[$WEEKDAY]}"     
  164.     MN=1$(date +%m)  
  165.     MN=$[MN-100]  
  166.     DN=1$(date +%d)  
  167.     DN=$[DN-100]  
  168.     DT="$MN$DN ${WEEKDAYS[$WEEKDAY]}"  
  169.     echo "$DT"  
  170. }  
  171.   
  172. # usage: rand_digit  
  173. 随机数字,0-9  
  174. rand_digit()  
  175. {  
  176.     S="$(date +%N)"  
  177.     echo "${S:5:1}"  
  178. }  
  179.   
  180. # usage: seconds_of_date [<date> [<time>]]  
  181. 获取指定日期的秒数(自1970年)  
  182. 比如:seconds_of_date "2010-02-27" 返回 1267200000  
  183. seconds_of_date()  
  184. {  
  185.     if [ "$1" ]; then  
  186.         date -d "$1 $2" +%s  
  187.     else  
  188.         date +%s  
  189.     fi  
  190. }  
  191.   
  192. # usage: date_of_seconds <seconds>  
  193. 根据秒数(自1970年)得到日期  
  194. 比如:date_of_seconds 1267200000 返回 2010-02-27  
  195. date_of_seconds()  
  196. {  
  197.     date -d "1970-01-01 UTC $1 seconds" "+%Y-%m-%d"  
  198. }  
  199.   
  200. # usage: datetime_of_seconds <seconds>  
  201. 根据秒数(自1970年)得到日期时间  
  202. 比如:datetime_of_seconds 1267257201 返回 2010-02-27 15:53:21  
  203. datetime_of_seconds()  
  204. {  
  205.     date -d "1970-01-01 UTC $1 seconds" "+%Y-%m-%d %H:%M:%S"  
  206. }  
  207.   
  208. # usage: leap_year <yyyy>  
  209. 判断是否闰年  
  210. 如果yyyy是闰年,退出码为0;否则非0  
  211. 典型示例如下:  
  212. # if leap_year 2010; then  
  213. #   echo "2010 is leap year";  
  214. # fi  
  215. # if leap_year 2008; then  
  216. #   echo "2008 is leap year";  
  217. # fi  
  218. 摘自脚本:datetime_util.sh (2007.06.11)  
  219. 注:这个脚本来自网络,略有修改(原脚本从标准输入获取年份,现改成通过参数指定)  
  220. # Shell program to read any year and find whether leap year or not  
  221. # -----------------------------------------------  
  222. # Copyright (c) 2005 nixCraft project <http://cyberciti.biz/fb/>  
  223. # This script is licensed under GNU GPL version 2.0 or above  
  224. # -------------------------------------------------------------------------  
  225. # This script is part of nixCraft shell script collection (NSSC)  
  226. # Visit http://bash.cyberciti.biz/ for more information.  
  227. # -------------------------------------------------------------------------  
  228. leap_year()  
  229. {  
  230.     # store year  
  231.     yy=$1  
  232.     isleap="false"  
  233.   
  234.     #echo -n "Enter year (yyyy) : "  
  235.     #read yy  
  236.   
  237.     # find out if it is a leap year or not  
  238.   
  239.     if [ $((yy % 4)) -ne 0 ] ; then  
  240.         : #  not a leap year : means do nothing and use old value of isleap  
  241.     elif [ $((yy % 400)) -eq 0 ] ; then  
  242.         # yes, it's a leap year  
  243.         isleap="true"  
  244.     elif [ $((yy % 100)) -eq 0 ] ; then  
  245.         : # not a leap year do nothing and use old value of isleap  
  246.     else  
  247.         # it is a leap year  
  248.         isleap="true"  
  249.     fi  
  250.     #echo $isleap  
  251.     if [ "$isleap" == "true" ]; then  
  252.         #  echo "$yy is leap year"  
  253.         return 0  
  254.     else  
  255.         #  echo "$yy is NOT leap year"  
  256.         return 1  
  257.     fi  
  258. }  
  259.   
  260. # usage: validity_of_date <yyyy> <mm> <dd>  
  261. 判断yyyy-mm-dd是否合法的日期  
  262. 如果是,退出码为0;否则非0  
  263. 典型示例如下:  
  264. # if validity_of_date 2007 02 03; then  
  265. #   echo "2007 02 03 is valid date"  
  266. # fi  
  267. # if validity_of_date 2007 02 28; then  
  268. #   echo "2007 02 28 is valid date"  
  269. # fi  
  270. # if validity_of_date 2007 02 29; then  
  271. #   echo "2007 02 29 is valid date"  
  272. # fi  
  273. # if validity_of_date 2007 03 00; then  
  274. #   echo "2007 03 00 is valid date"  
  275. # fi  
  276. 摘自脚本:datetime_util.sh (2007.06.11)  
  277. 注:这个脚本来自网络,略有修改(原脚本从标准输入获取年月日,现改成通过参数指定)  
  278. # Shell program to find the validity of a given date  
  279. # -----------------------------------------------  
  280. # Copyright (c) 2005 nixCraft project <http://cyberciti.biz/fb/>  
  281. # This script is licensed under GNU GPL version 2.0 or above  
  282. # -------------------------------------------------------------------------  
  283. # This script is part of nixCraft shell script collection (NSSC)  
  284. # Visit http://bash.cyberciti.biz/ for more information.  
  285. # -------------------------------------------------------------------------  
  286. validity_of_date()  
  287. {  
  288.     # store day, month and year  
  289.     yy=$1  
  290.     mm=$2  
  291.     dd=$3  
  292.   
  293.     # store number of days in a month  
  294.     days=0  
  295.   
  296.     # get day, month and year  
  297.     #echo -n "Enter day (dd) : "  
  298.     #read dd  
  299.   
  300.     #echo -n "Enter month (mm) : "  
  301.     #read mm  
  302.   
  303.     #echo -n "Enter year (yyyy) : "  
  304.     #read yy  
  305.   
  306.     # if month is negative (<0) or greater than 12   
  307.     # then it is invalid month  
  308.     if [ $mm -le 0 -o $mm -gt 12 ]; then  
  309.         #echo "$mm is invalid month."  
  310.         return 1  
  311.     fi  
  312.   
  313.     # Find out number of days in given month  
  314.     case $mm in   
  315.         1) days=31;;  
  316.         01) days=31;;  
  317.         2) days=28 ;;  
  318.         02) days=28 ;;  
  319.         3) days=31 ;;  
  320.         03) days=31 ;;  
  321.         4) days=30 ;;  
  322.         04) days=30 ;;  
  323.         5) days=31 ;;  
  324.         05) days=31 ;;  
  325.         6) days=30 ;;  
  326.         06) days=30 ;;  
  327.         7) days=31 ;;  
  328.         07) days=31 ;;  
  329.         8) days=31 ;;  
  330.         08) days=31 ;;  
  331.         9) days=30 ;;  
  332.         09) days=30 ;;  
  333.         10) days=31 ;;  
  334.         11) days=30 ;;  
  335.         12) days=31 ;;  
  336.         *) days=-1;;  
  337.     esac  
  338.   
  339.     # find out if it is a leap year or not  
  340.   
  341.     if [ $mm -eq 2 ]; then # if it is feb month then only check of leap year  
  342.         if [ $((yy % 4)) -ne 0 ] ; then  
  343.             : #  not a leap year : means do nothing and use old value of days  
  344.         elif [ $((yy % 400)) -eq 0 ] ; then  
  345.             # yes, it's a leap year  
  346.             days=29  
  347.         elif [ $((yy % 100)) -eq 0 ] ; then  
  348.             : # not a leap year do nothing and use old value of days  
  349.         else  
  350.             # it is a leap year  
  351.             days=29  
  352.         fi  
  353.     fi  
  354.   
  355.     #echo $days  
  356.   
  357.     # if day is negative (<0) and if day is more than   
  358.     # that months days then day is invaild  
  359.     if [ $dd -le 0 -o $dd -gt $days ]; then  
  360.         #echo "$dd day is invalid"  
  361.         return 3  
  362.     fi  
  363.   
  364.     # if no error that means date dd/mm/yyyy is valid one  
  365.     #echo "$dd/$mm/$yy is a vaild date"  
  366.     #echo "$yy-$mm-$dd is a valid date"  
  367.     #echo "valid"  
  368.     return 0  
  369. }  
  370.   
  371. # usage: days_of_month <mm> <yyyy>  
  372. 获取yyyymm月的天数,注意参数顺序  
  373. 比如:days_of_month 2 2007 结果是28  
  374. days_of_month()  
  375. {  
  376.     # store day, month and year  
  377.     mm=$1  
  378.     yy=$2  
  379.   
  380.     # store number of days in a month  
  381.     days=0  
  382.   
  383.     # get day, month and year  
  384.     #echo -n "Enter day (dd) : "  
  385.     #read dd  
  386.   
  387.     #echo -n "Enter month (mm) : "  
  388.     #read mm  
  389.   
  390.     #echo -n "Enter year (yyyy) : "  
  391.     #read yy  
  392.   
  393.     # if month is negative (<0) or greater than 12   
  394.     # then it is invalid month  
  395.     if [ $mm -le 0 -o $mm -gt 12 ]; then  
  396.         #echo "$mm is invalid month."  
  397.         echo -1  
  398.         return 1  
  399.     fi  
  400.   
  401.     # Find out number of days in given month  
  402.     case $mm in   
  403.         1) days=31;;  
  404.         01) days=31;;  
  405.         2) days=28 ;;  
  406.         02) days=28 ;;  
  407.         3) days=31 ;;  
  408.         03) days=31 ;;  
  409.         4) days=30 ;;  
  410.         04) days=30 ;;  
  411.         5) days=31 ;;  
  412.         05) days=31 ;;  
  413.         6) days=30 ;;  
  414.         06) days=30 ;;  
  415.         7) days=31 ;;  
  416.         07) days=31 ;;  
  417.         8) days=31 ;;  
  418.         08) days=31 ;;  
  419.         9) days=30 ;;  
  420.         09) days=30 ;;  
  421.         10) days=31 ;;  
  422.         11) days=30 ;;  
  423.         12) days=31 ;;  
  424.         *) days=-1;;  
  425.     esac  
  426.   
  427.     # find out if it is a leap year or not  
  428.   
  429.     if [ $mm -eq 2 ]; then # if it is feb month then only check of leap year  
  430.         if [ $((yy % 4)) -ne 0 ] ; then  
  431.             : #  not a leap year : means do nothing and use old value of days  
  432.         elif [ $((yy % 400)) -eq 0 ] ; then  
  433.             # yes, it's a leap year  
  434.             days=29  
  435.         elif [ $((yy % 100)) -eq 0 ] ; then  
  436.             : # not a leap year do nothing and use old value of days  
  437.         else  
  438.             # it is a leap year  
  439.             days=29  
  440.         fi  
  441.     fi  
  442.   
  443.     echo $days  
  444. }  

 

文件:test_datetime.sh

Bash代码  

  1. #!/bin/sh  
  2.   
  3. # TODO: 注意根据datetime.sh的实际位置更改  
  4. . /opt/shtools/commons/datetime.sh  
  5.   
  6. echo "当前时间(date):$(date)"  
  7. echo "昨天(yesterday):$(yesterday)"  
  8. echo "今天(today):$(today)"  
  9. echo "现在(now):$(now)"  
  10. echo "现在(curtime):$(curtime)"  
  11. echo "上月(last_month):$(last_month)"  
  12. echo "上月(last_month_packed):$(last_month_packed)"  
  13. echo "上月第一天(first_date_of_last_month):$(first_date_of_last_month)"  
  14. echo "上月最后一天(last_date_of_last_month):$(last_date_of_last_month)"  
  15. echo "今天星期几(day_of_week):$(day_of_week)"  
  16. echo "上个小时(last_hour):$(last_hour)"  
  17. echo "当前的小时(the_hour):$(the_hour)"  
  18. echo "当前的分钟(the_minute):$(the_minute)"  
  19. echo "当前的秒钟(the_second):$(the_second)"  
  20. echo "当前的年份(the_year):$(the_year)"  
  21. echo "当前的月份(the_month):$(the_month)"  
  22. echo "当前的日期(the_date):$(the_date)"  
  23. echo "前天(days_ago 2):$(days_ago 2)"  
  24. echo "明天(days_ago -1):$(days_ago -1)"  
  25. echo "后天(days_ago -2):$(days_ago -2)"  
  26. echo "十天前的日期(days_ago 10):$(days_ago 10)"  
  27. echo "中文的日期星期(chinese_date_and_week):$(chinese_date_and_week)"  
  28. echo "随机数字(rand_digit):$(rand_digit)"  
  29. echo "随机数字(rand_digit):$(rand_digit)"  
  30. echo "1970年来的秒数(seconds_of_date):$(seconds_of_date)"  
  31. echo "1970年来的秒数(seconds_of_date 2010-02-27):$(seconds_of_date 2010-02-27)"  
  32. echo "1970年来的秒数(seconds_of_date 2010-02-27 15:53:21):$(seconds_of_date 2010-02-27 15:53:21)"  
  33. echo "1970年来的秒数对应的日期(date_of_seconds 1267200000):$(date_of_seconds 1267200000)"  
  34. echo "1970年来的秒数对应的日期时间(datetime_of_seconds 1267257201):$(datetime_of_seconds 1267257201)"  
  35.   
  36. if leap_year 2010; then  
  37.     echo "2010年是闰年";  
  38. fi  
  39. if leap_year 2008; then  
  40.     echo "2008年是闰年";  
  41. fi  
  42. if validity_of_date 2007 02 03; then  
  43.     echo "2007 02 03 日期合法"  
  44. fi  
  45. if validity_of_date 2007 02 28; then  
  46.     echo "2007 02 28 日期合法"  
  47. fi  
  48. if validity_of_date 2007 02 29; then  
  49.     echo "2007 02 29 日期合法"  
  50. fi  
  51. if validity_of_date 2007 03 00; then  
  52.     echo "2007 03 00 日期合法"  
  53. fi  
  54.   
  55. echo "20102月的天数(days_of_month 2 2010):$(days_of_month 2 2010)"  
  56. echo "20082月的天数(days_of_month 2 2008):$(days_of_month 2 2008)"  

 

文件:test_datetime.txt

 

Text代码  

  1. 当前时间(date):六  2 27 15:58:28 CST 2010  
  2. 昨天(yesterday):2010-02-26  
  3. 今天(today):2010-02-27  
  4. 现在(now):2010-02-27 15:58:28.734817000  
  5. 现在(curtime):2010-02-27 15:58:28  
  6. 上月(last_month):2010-01  
  7. 上月(last_month_packed):201001  
  8. 上月第一天(first_date_of_last_month):2010-01-01  
  9. 上月最后一天(last_date_of_last_month):2010-01-31  
  10. 今天星期几(day_of_week):6  
  11. 上个小时(last_hour):2010-02-27-14  
  12. 当前的小时(the_hour):15  
  13. 当前的分钟(the_minute):58  
  14. 当前的秒钟(the_second):28  
  15. 当前的年份(the_year):2010  
  16. 当前的月份(the_month):2  
  17. 当前的日期(the_date):27  
  18. 前天(days_ago 2):2010-02-25  
  19. 明天(days_ago -1):2010-02-28  
  20. 后天(days_ago -2):2010-03-01  
  21. 十天前的日期(days_ago 10):2010-02-17  
  22. 中文的日期星期(chinese_date_and_week):227 星期六  
  23. 随机数字(rand_digit):5  
  24. 随机数字(rand_digit):9  
  25. 1970年来的秒数(seconds_of_date):1267257508  
  26. 1970年来的秒数(seconds_of_date 2010-02-27):1267200000  
  27. 1970年来的秒数(seconds_of_date 2010-02-27 15:53:21):1267257201  
  28. 1970年来的秒数对应的日期(date_of_seconds 1267200000):2010-02-27  
  29. 1970年来的秒数对应的日期时间(datetime_of_seconds 1267257201):2010-02-27 15:53:21  
  30. 2008年是闰年  
  31. 2007 02 03 日期合法  
  32. 2007 02 28 日期合法  
  33. 20102月的天数(days_of_month 2 2010):28  
  34. 20082月的天数(days_of_month 2 2008):29  
 
已使用 Microsoft OneNote 2016 创建。