第一章:The Missing Code Library--7.合法化日期格式
2012-12-07 10:55
435 查看
所有的合法化输入脚本中,最有挑战的一个非属于操作日期不可。它的目的是确保一个给定的日期在现实中是存在的。如果忽略闰年,这个任务并不难,因为每年的日期都很有一致性。这种情况下,我们所要做的仅仅是将一个给定的日期和每个月的天数进行比较。但是为了计算闰年,就需要增加一些额外的逻辑了。 下面就是一个计算闰年的规则集合:
1.不能被4整除的不是闰年
2.能被4和400同时整除的是闰年
3.能被4整除,但不能被400整除,可又能被100整除的,不是闰年
4.除了上述情况,所有能被4整除的都是闰年
代码:
validdate.sh
运行脚本:
要运行脚本,只需要在命令行给出一个格式为“月 日 年”的日期。月可以是三个字母的缩写、完整月份或者是数字;但是年必须是一个4位的数字。
运行结果:
分析脚本:
类似于这个脚本中的思路,我们也可以写一个合法化时间的脚步。时间的表示格式有:使用24小时制;使用am/pm后缀。在冒号处切割时间的值,确保分钟和秒数(如果有给出)在0-60之间,如果是am/pm的就再核实下第一个值是否在0-12之间,或者是24小时制的是否在0-24之间。(幸运的是,时间中有闰秒和其它细小的变动来保持日历的平衡,所以在日常的基础上我们完全可以忽略它们)
1.不能被4整除的不是闰年
2.能被4和400同时整除的是闰年
3.能被4整除,但不能被400整除,可又能被100整除的,不是闰年
4.除了上述情况,所有能被4整除的都是闰年
代码:
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位的数字。
运行结果:
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之间。(幸运的是,时间中有闰秒和其它细小的变动来保持日历的平衡,所以在日常的基础上我们完全可以忽略它们)
相关文章推荐
- 第一章:The Missing Code Library--7.合法化日期格式
- 第一章:The Missing Code Library--3.正常化日期格式
- 第一章:The Missing Code Library--3.正常化日期格式
- 第一章:The Missing Code Library--2.合法化输入
- 第一章:The Missing Code Library--5.合法化整型输入
- 第一章:The Missing Code Library--2.合法化输入
- 第一章:The Missing Code Library--6.合法化浮点数输入
- 第一章:The Missing Code Library--5.合法化整型输入
- 第一章:The Missing Code Library--6.合法化浮点数输入
- 第一章:The Missing Code Library--4.优雅的表示大数
- 第一章:The Missing Code Library--11.ANSI颜色序列
- 第一章:The Missing Code Library--1.在系统路径PATH中寻找程序
- 第一章:The Missing Code Library--8.避免不合要求的echo方法
- 第一章:The Missing Code Library--9.一个任意精度浮点计算器
- 第一章:The Missing Code Library--10.锁定文件
- 第一章:The Missing Code Library--12.建立一个Shell脚本库
- 第一章:The Missing Code Library--1.在系统路径PATH中寻找程序
- 第一章:The Missing Code Library--13.调试Shell脚本
- 第一章:The Missing Code Library--8.避免不合要求的echo方法
- 第一章:The Missing Code Library--4.优雅的表示大数