灯火互联
管理员
管理员
  • 注册日期2011-07-27
  • 发帖数41778
  • QQ
  • 火币41290枚
  • 粉丝1086
  • 关注100
  • 终身成就奖
  • 最爱沙发
  • 忠实会员
  • 灌水天才奖
  • 贴图大师奖
  • 原创先锋奖
  • 特殊贡献奖
  • 宣传大使奖
  • 优秀斑竹奖
  • 社区明星
阅读:2422回复:0

合法化日期格式脚本

楼主#
更多 发布于:2013-05-14 10:32
合法化日期格式脚本

所有的合法化输入脚本中,最有挑战的一个非属于操作日期不可。它的目的是确保一个给定的日期在现实中是存在的。如果忽略闰年,这个任务并不难,因为每年的日期都很有一致性。这种情况下,我们所要做的仅仅是将一个给定的日期和每个月的天数进行比较。但是为了计算闰年,就需要增加一些额外的逻辑了。      

下面就是一个计算闰年的规则集合:
1.不能被4整除的不是闰年
2.能被4和400同时整除的是闰年
3.能被4整除,但不能被400整除,可又能被100整除的,不是闰年
4.除了上述情况,所有能被4整除的都是闰年

代码:

01
validdate.sh
02
#!/bin/sh
03
 
04
# validdate.sh--合法化一个日期,兼顾到闰年
05
 
06
exceedsDaysinMonth()
07
{
08
    # 给定一个月份,如果给定的天小于等于该月的最大天数,返回0
09
    # 否则,返回1
10
 
11
    case $(echo $1 | tr '[:upper:]' '[:lower:]') in
12
        jan* ) days=31;;  feb* ) days=28;;
13
        mar* ) days=31;;  apr* ) days=30;;
14
        may* ) days=31;;  jun* ) days=30;;
15
        jul* ) days=31;;  aug* ) days=31;;
16
        sep* ) days=30;;  oct* ) days=31;;
17
        nov* ) days=30;;  dec* ) days=31;;
18
        *) echo "$0: Unknown month name $1" >&2; exit 1
19
    esac
20
 
21
    if [ $2 -lt 1 -o $2 -gt $days ]; then
22
        return 1
23
    else
24
        return 0    # 天的数字合法
25
    fi
26
}
27
 
28
isLeepYear()
29
{
30
    # 如果是闰年,函数返回0;否则,返回1
31
    # 判断闰年的规则是:如上所述的4点
32
 
33
    year=$1
34
 
35
    if [ "$((year%4))" -ne 0 ]; then
36
        return 1
37
    elif [ "$((year%400))" ]; then
38
        return 0
39
    elif [ "$((year%100))" ]; then
40
        return 1
41
    else
42
        return 0
43
    fi
44
}
45
 
46
# 开始脚本的主要部分
47
 
48
if [ $# -ne 3 ]; then
49
    echo "用法: $0 月 日 年" >&2
50
    echo "正确的输入格式是: August 3 1962和8 3 2002" >&2
51
    exit 1
52
fi
53
 
54
# 正常化日期,
55
 
56
newdate="$(normdate.sh "$@")"
57
 
58
if [ $? -eq 1 ]; then
59
    exit 1         # normdate报告的错误状态
60
fi
61
 
62
month="$(echo $newdate | cut -d\  -f1)"     # 注意,-d\后面到-f1之间有2个空格,反斜线\的作用是转义空格
63
  day="$(echo $newdate | cut -d\  -f2)"
64
 year="$(echo $newdate | cut -d\  -f3)"
65
 
66
# 既然日期已经正常化了,那就测试下天数的值是否正确
67
 
68
if ! exceedsDaysinMonth $month "$2"; then
69
    if [ "$month" = "Feb" -a "$2" -eq "29" ]; then
70
        if ! isLeepYear $3; then
71
            echo "$0: $3 不是一个闰年,所以2月没有29天." >&2
72
            exit 1
73
        fi
74
    else
75
        echo "$0: 错误的天数: $month 没有 $2 天." >&2
76
        exit 1
77
    fi
78
fi
79
 
80
echo "正确日期: $newdate"
81
 
82
exit 0
运行脚本:
要运行脚本,只需要在命令行给出一个格式为“月 日 年”的日期。月可以是三个字母的缩写、完整月份或者是数字;但是年必须是一个4位的数字。

运行结果:

1
validdate.sh august 3 1960
2
正确日期: Aug 3 1960
3
validdate.sh 9 3 2001
4
正确日期: Sep 3 2001
5
validdate.sh feb 29 2004
6
正确日期: Feb 29 2004
7
./validdate.sh feb 29 2006
8
./validdate.sh: 2006 不是一个闰年?所以2月没有29天.
分析脚本:
类似于这个脚本中的思路,我们也可以写一个合法化时间的脚步。时间的表示格式有:使用24小时制;使用am/pm后缀。在冒号处切割时间的值,确保分钟和秒数(如果有给出)在0-60之间,如果是am/pm的就再核实下第一个值是否在0-12之间,或者是24小时制的是否在0-24之间。(幸运的是,时间中有闰秒和其它细小的变动来保持日历的平衡,所以在日常的基础上我们完全可以忽略它们)

喜欢0 评分0
游客

返回顶部