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

在编写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. Copyright (c) 2010 codingstandards. All rights reserved.

  3. file: datetime.sh

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

  5. license: LGPL

  6. author: codingstandards

  7. email: codingstandards@gmail.com

  8. version: 1.0

  9. date: 2010.02.27

  10. usage: yesterday

  11. 昨天

  12. 比如今天是2010年2月27日,那么结果就是2010-02-26

  13. yesterday()

  14. {

  15. date —date=‘1 day ago’ +%Y-%m-%d

  16. }

  17. usage: today

  18. 今天

  19. 比如今天是2010年2月27日,那么结果就是2010-02-27

  20. today()

  21. {

  22. date +%Y-%m-%d

  23. }

  24. usage: now

  25. 现在,包括日期和时间、纳秒

  26. 比如:2010-02-27 11:29:52.991774000

  27. now()

  28. {

  29. date ”+%Y-%m-%d %H:%M:%S.%N”

  30. }

  31. usage: curtime

  32. 当前时间,包括日期和时间

  33. 比如:2010-02-27 11:51:04

  34. curtime()

  35. {

  36. date ’+%Y-%m-%d %H:%M:%S’

  37. 也可写成:date ’+%F %T’

  38. }

  39. usage: last_month

  40. 取上个月的年月

  41. 比如:2010-01

  42. last_month()

  43. {

  44. date —date=‘1 month ago’ ’+%Y-%m’

  45. }

  46. usage: last_month_packed

  47. 取上个月的年月

  48. 比如:201001

  49. last_month_packed()

  50. {

  51. date —date=‘1 month ago’ ’+%Y%m’

  52. }

  53. usage: first_date_of_last_month

  54. 取上个月的第一天

  55. 比如本月是2010年2月,那么结果就是2010-01-01

  56. first_date_of_last_month()

  57. {

  58. date —date=‘1 month ago’ ’+%Y-%m-01’

  59. }

  60. usage: last_date_of_last_month

  61. 取上个月的最后一天

  62. 比如当前是2010年2月,那么结果就是2010-01-31

  63. last_date_of_last_month()

  64. {

  65. date —date=”$(date +%e) days ago” ’+%Y-%m-%d’

  66. }

  67. usage: day_of_week

  68. 今天的星期

  69. day of week (0..6); 0 represents Sunday

  70. day_of_week()

  71. {

  72. date +%w

  73. }

  74. usage: last_hour

  75. 上个小时

  76. 比如:2010-02-27-10

  77. 适合处理log4j生成的日志文件名

  78. last_hour()

  79. {

  80. date —date=‘1 hour ago’ +%Y-%m-%d-%H

  81. }

  82. usage: the_hour

  83. 当前的小时,为方便算术比较,结果不以0开头

  84. 比如:12

  85. the_hour()

  86. {

  87. #date +%H # hour (00..23)

  88. date +%k # hour ( 0..23)

  89. }

  90. usage: the_minute

  91. 当前的分钟,为方便算术比较,结果不以0开头

  92. 比如:

  93. the_minute()

  94. {

  95. MM=$(date +%M) # minute (00..59)

  96. echo $[1$MM-100]

  97. }

  98. usage: the_second

  99. 当前的秒数

  100. 比如:

  101. the_second()

  102. {

  103. SS=$(date +%S) # second (00..60); the 60 is necessary to accommodate a leap second

  104. echo $[1$SS-100]

  105. }

  106. usage: the_year

  107. 当前的年份 year (1970…)

  108. 比如:2010

  109. the_year()

  110. {

  111. date +%Y

  112. }

  113. usage: the_month

  114. 当前的月份,为方便算术比较,结果不以0开头

  115. 比如:2

  116. the_month()

  117. {

  118. M=$(date +%m) # month (01..12)

  119. echo $[1$M-100]

  120. }

  121. usage: the_date

  122. 当前的日期,为方便算术比较,结果不以0开头

  123. 比如:27

  124. the_date()

  125. {

  126. date +%e # day of month, blank padded ( 1..31)

  127. }

  128. usage: days_ago

  129. 取n天前的日期

  130. 比如:days_ago 0就是今天,days_ago 1就是昨天,days_ago 2就是前天,days_ago -1就是明天

  131. 格式:2010-02-27

  132. days_ago()

  133. {

  134. date —date=“$1 days ago” +%Y-%m-%d

  135. }

  136. usage: chinese_date_and_week()

  137. 打印中文的日期和星期

  138. 比如:2月27日 星期六

  139. chinese_date_and_week()

  140. {

  141. WEEKDAYS=(星期日 星期一 星期二 星期三 星期四 星期五 星期六)

  142. WEEKDAY=$(date +%w)

  143. #DT=”$(date +%Y年%m月%d日) ${WEEKDAYS[$WEEKDAY]}”

  144. MN=1$(date +%m)

  145. MN=$[MN-100]

  146. DN=1$(date +%d)

  147. DN=$[DN-100]

  148. DT=“$MN月$DN日 ${WEEKDAYS[$WEEKDAY]}”

  149. echo “$DT”

  150. }

  151. usage: rand_digit

  152. 随机数字,0-9

  153. rand_digit()

  154. {

  155. S=”$(date +%N)”

  156. echo ”${S:5:1}”

  157. }

  158. usage: seconds_of_date [ [

  159. 获取指定日期的秒数(自1970年)

  160. 比如:seconds_of_date “2010-02-27” 返回 1267200000

  161. seconds_of_date()

  162. {

  163. if [ “$1” ]; then

  164. date -d “$1 $2” +%s

  165. else

  166. date +%s

  167. fi

  168. }

  169. usage: date_of_seconds

  170. 根据秒数(自1970年)得到日期

  171. 比如:date_of_seconds 1267200000 返回 2010-02-27

  172. date_of_seconds()

  173. {

  174. date -d “1970-01-01 UTC $1 seconds” ”+%Y-%m-%d”

  175. }

  176. usage: datetime_of_seconds

  177. 根据秒数(自1970年)得到日期时间

  178. 比如:datetime_of_seconds 1267257201 返回 2010-02-27 15:53:21

  179. datetime_of_seconds()

  180. {

  181. date -d “1970-01-01 UTC $1 seconds” ”+%Y-%m-%d %H:%M:%S”

  182. }

  183. usage: leap_year

  184. 判断是否闰年

  185. 如果yyyy是闰年,退出码为0;否则非0

  186. 典型示例如下:

  187. if leap_year 2010; then

  188. echo “2010 is leap year”;

  189. fi

  190. if leap_year 2008; then

  191. echo “2008 is leap year”;

  192. fi

  193. 摘自脚本:datetime_util.sh (2007.06.11)

  194. 注:这个脚本来自网络,略有修改(原脚本从标准输入获取年份,现改成通过参数指定)

  195. Shell program to read any year and find whether leap year or not

  196. -----------------------------------------------

  197. Copyright (c) 2005 nixCraft project <http://cyberciti.biz/fb/>

  198. This script is licensed under GNU GPL version 2.0 or above

  199. -------------------------------------------------------------------------

  200. This script is part of nixCraft shell script collection (NSSC)

  201. Visit http://bash.cyberciti.biz/ for more information.

  202. -------------------------------------------------------------------------

  203. leap_year()

  204. {

  205. store year

  206. yy=$1

  207. isleap=“false”

  208. #echo -n “Enter year (yyyy) : ”

  209. #read yy

  210. find out if it is a leap year or not

  211. if [ $((yy % 4)) -ne 0 ] ; then

  212. : # not a leap year : means do nothing and use old value of isleap

  213. elif [ $((yy % 400)) -eq 0 ] ; then

  214. yes, it’s a leap year

  215. isleap=“true”

  216. elif [ $((yy % 100)) -eq 0 ] ; then

  217. : # not a leap year do nothing and use old value of isleap

  218. else

  219. it is a leap year

  220. isleap=“true”

  221. fi

  222. #echo $isleap

  223. if [ “$isleap” == “true” ]; then

  224. echo “$yy is leap year”

  225. return 0

  226. else

  227. echo “$yy is NOT leap year”

  228. return 1

  229. fi

  230. }

  231. usage: validity_of_date

  232. 判断yyyy-mm-dd是否合法的日期

  233. 如果是,退出码为0;否则非0

  234. 典型示例如下:

  235. if validity_of_date 2007 02 03; then

  236. echo “2007 02 03 is valid date”

  237. fi

  238. if validity_of_date 2007 02 28; then

  239. echo “2007 02 28 is valid date”

  240. fi

  241. if validity_of_date 2007 02 29; then

  242. echo “2007 02 29 is valid date”

  243. fi

  244. if validity_of_date 2007 03 00; then

  245. echo “2007 03 00 is valid date”

  246. fi

  247. 摘自脚本:datetime_util.sh (2007.06.11)

  248. 注:这个脚本来自网络,略有修改(原脚本从标准输入获取年月日,现改成通过参数指定)

  249. Shell program to find the validity of a given date

  250. -----------------------------------------------

  251. Copyright (c) 2005 nixCraft project <http://cyberciti.biz/fb/>

  252. This script is licensed under GNU GPL version 2.0 or above

  253. -------------------------------------------------------------------------

  254. This script is part of nixCraft shell script collection (NSSC)

  255. Visit http://bash.cyberciti.biz/ for more information.

  256. -------------------------------------------------------------------------

  257. validity_of_date()

  258. {

  259. store day, month and year

  260. yy=$1

  261. mm=$2

  262. dd=$3

  263. store number of days in a month

  264. days=0

  265. get day, month and year

  266. #echo -n “Enter day (dd) : ”

  267. #read dd

  268. #echo -n “Enter month (mm) : ”

  269. #read mm

  270. #echo -n “Enter year (yyyy) : ”

  271. #read yy

  272. if month is negative (<0) or greater than 12

  273. then it is invalid month

  274. if [ $mm -le 0 -o $mm -gt 12 ]; then

  275. #echo “$mm is invalid month.”

  276. return 1

  277. fi

  278. Find out number of days in given month

  279. case $mm in

    1. days=31;;
    1. days=31;;
    1. days=28 ;;
    1. days=28 ;;
    1. days=31 ;;
    1. days=31 ;;
    1. days=30 ;;
    1. days=30 ;;
    1. days=31 ;;
    1. days=31 ;;
    1. days=30 ;;
    1. days=30 ;;
    1. days=31 ;;
    1. days=31 ;;
    1. days=31 ;;
    1. days=31 ;;
    1. days=30 ;;
    1. days=30 ;;
    1. days=31 ;;
    1. days=30 ;;
    1. days=31 ;;
  280. *) days=-1;;

  281. esac

  282. find out if it is a leap year or not

  283. if [ $mm -eq 2 ]; then # if it is feb month then only check of leap year

  284. if [ $((yy % 4)) -ne 0 ] ; then

  285. : # not a leap year : means do nothing and use old value of days

  286. elif [ $((yy % 400)) -eq 0 ] ; then

  287. yes, it’s a leap year

  288. days=29

  289. elif [ $((yy % 100)) -eq 0 ] ; then

  290. : # not a leap year do nothing and use old value of days

  291. else

  292. it is a leap year

  293. days=29

  294. fi

  295. fi

  296. #echo $days

  297. if day is negative (<0) and if day is more than

  298. that months days then day is invaild

  299. if [ $dd -le 0 -o $dd -gt $days ]; then

  300. #echo “$dd day is invalid”

  301. return 3

  302. fi

  303. if no error that means date dd/mm/yyyy is valid one

  304. #echo “$dd/$mm/$yy is a vaild date”

  305. #echo “$yy-$mm-$dd is a valid date”

  306. #echo “valid”

  307. return 0

  308. }

  309. usage: days_of_month

  310. 获取yyyy年mm月的天数,注意参数顺序

  311. 比如:days_of_month 2 2007 结果是28

  312. days_of_month()

  313. {

  314. store day, month and year

  315. mm=$1

  316. yy=$2

  317. store number of days in a month

  318. days=0

  319. get day, month and year

  320. #echo -n “Enter day (dd) : ”

  321. #read dd

  322. #echo -n “Enter month (mm) : ”

  323. #read mm

  324. #echo -n “Enter year (yyyy) : ”

  325. #read yy

  326. if month is negative (<0) or greater than 12

  327. then it is invalid month

  328. if [ $mm -le 0 -o $mm -gt 12 ]; then

  329. #echo “$mm is invalid month.”

  330. echo -1

  331. return 1

  332. fi

  333. Find out number of days in given month

  334. case $mm in

    1. days=31;;
    1. days=31;;
    1. days=28 ;;
    1. days=28 ;;
    1. days=31 ;;
    1. days=31 ;;
    1. days=30 ;;
    1. days=30 ;;
    1. days=31 ;;
    1. days=31 ;;
    1. days=30 ;;
    1. days=30 ;;
    1. days=31 ;;
    1. days=31 ;;
    1. days=31 ;;
    1. days=31 ;;
    1. days=30 ;;
    1. days=30 ;;
    1. days=31 ;;
    1. days=30 ;;
    1. days=31 ;;
  335. *) days=-1;;

  336. esac

  337. find out if it is a leap year or not

  338. if [ $mm -eq 2 ]; then # if it is feb month then only check of leap year

  339. if [ $((yy % 4)) -ne 0 ] ; then

  340. : # not a leap year : means do nothing and use old value of days

  341. elif [ $((yy % 400)) -eq 0 ] ; then

  342. yes, it’s a leap year

  343. days=29

  344. elif [ $((yy % 100)) -eq 0 ] ; then

  345. : # not a leap year do nothing and use old value of days

  346. else

  347. it is a leap year

  348. days=29

  349. fi

  350. fi

  351. echo $days

  352. }

文件:test_datetime.sh

Bash代码

  1. #!/bin/sh

  2. TODO: 注意根据datetime.sh的实际位置更改

  3. . /opt/shtools/commons/datetime.sh

  4. echo “当前时间(date):$(date)”

  5. echo “昨天(yesterday):$(yesterday)”

  6. echo “今天(today):$(today)”

  7. echo “现在(now):$(now)”

  8. echo “现在(curtime):$(curtime)”

  9. echo “上月(last_month):$(last_month)”

  10. echo “上月(last_month_packed):$(last_month_packed)”

  11. echo “上月第一天(first_date_of_last_month):$(first_date_of_last_month)”

  12. echo “上月最后一天(last_date_of_last_month):$(last_date_of_last_month)”

  13. echo “今天星期几(day_of_week):$(day_of_week)”

  14. echo “上个小时(last_hour):$(last_hour)”

  15. echo “当前的小时(the_hour):$(the_hour)”

  16. echo “当前的分钟(the_minute):$(the_minute)”

  17. echo “当前的秒钟(the_second):$(the_second)”

  18. echo “当前的年份(the_year):$(the_year)”

  19. echo “当前的月份(the_month):$(the_month)”

  20. echo “当前的日期(the_date):$(the_date)”

  21. echo “前天(days_ago 2):$(days_ago 2)”

  22. echo “明天(days_ago -1):$(days_ago -1)”

  23. echo “后天(days_ago -2):$(days_ago -2)”

  24. echo “十天前的日期(days_ago 10):$(days_ago 10)”

  25. echo “中文的日期星期(chinese_date_and_week):$(chinese_date_and_week)”

  26. echo “随机数字(rand_digit):$(rand_digit)”

  27. echo “随机数字(rand_digit):$(rand_digit)”

  28. echo “自1970年来的秒数(seconds_of_date):$(seconds_of_date)”

  29. echo “自1970年来的秒数(seconds_of_date 2010-02-27):$(seconds_of_date 2010-02-27)”

  30. echo “自1970年来的秒数(seconds_of_date 2010-02-27 15:53:21):$(seconds_of_date 2010-02-27 15:53:21)”

  31. echo “自1970年来的秒数对应的日期(date_of_seconds 1267200000):$(date_of_seconds 1267200000)”

  32. echo “自1970年来的秒数对应的日期时间(datetime_of_seconds 1267257201):$(datetime_of_seconds 1267257201)”

  33. if leap_year 2010; then

  34. echo “2010年是闰年”;

  35. fi

  36. if leap_year 2008; then

  37. echo “2008年是闰年”;

  38. fi

  39. if validity_of_date 2007 02 03; then

  40. echo “2007 02 03 日期合法”

  41. fi

  42. if validity_of_date 2007 02 28; then

  43. echo “2007 02 28 日期合法”

  44. fi

  45. if validity_of_date 2007 02 29; then

  46. echo “2007 02 29 日期合法”

  47. fi

  48. if validity_of_date 2007 03 00; then

  49. echo “2007 03 00 日期合法”

  50. fi

  51. echo “2010年2月的天数(days_of_month 2 2010):$(days_of_month 2 2010)”

  52. echo “2008年2月的天数(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):2月27日 星期六

  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. 2010年2月的天数(days_of_month 2 2010):28

  34. 2008年2月的天数(days_of_month 2 2008):29

#shell-scripting