在unix中验证DD-MM-YYYY格式的日期

时间:2014-12-09 13:25:52

标签: bash unix arguments

如何在Unix中验证日期。
日期格式为DD-MM-YYYY的日期 例如,如果我运行一个脚本./ValidateDate.sh DD-MM-YYYY,那么它应该检查日期是否采用这种格式,并且日期是否存在。
如果日期有效且格式如上,则继续执行下一条其他打印消息'无效日期'

感谢。

4 个答案:

答案 0 :(得分:3)

嗯......这是一个很好的可以o'蠕虫。

您创建的任何shell脚本可能无法在所有各种版本的Unix / Linux上运行。

BSD date命令(在OS X和Solaris上找到)在接收日期和验证格式方面做得很好。它要求您指定日期格式,但一旦这样做,它就没有问题:

if date -j -f "%d-%m-%Y" "$DATE" 2>&1 > /dev/null # No output
then
    echo "ERROR: Date '$DATE' is not a valid format."
    exit 2
else
    echo "Date is '$DATE'."
fi

Linux和其他使用GNU日期的系统也可以验证日期,但使用不同的语法:

date -d "$DATE" 2>&1 /dev/null   # With a bit of luck this will work...
if $? -ne 0
then
    echo "ERROR: Date '$DATE' is not a valid format."
else
    echo "Date is '$DATE'."
fi

我说带点运气因为它可以通过date命令来确定您的约会格式。这通常有效,并且可以使用YYYY-MM-DD格式,但这可能令人困惑:

想象一下:

$ DATE="15/6/2014"              # It's June 15, 2014
$ date -d "$DATE"
date: invalid date `15/6/2014'  # Invalid?

这是因为在我的时区,dd/mm/yyyy格式不是有效格式。在我的时区,日期应为mm/dd/yyyy。为了解决这个问题,您可以使用Wintermute's建议,并在使用GNU的日期格式之前将日期格式化为ISO格式。

更多通用的可能性是使用Perl或Python来判断日期是否正确:

if perl -mTime::Piece -e "Time::Piece->strptime(\"$DATE\", \"%Y-%m-%d\")" 2> /dev/null
then
    echo "ERROR: Date '$DATE' is not a valid format."
else
    echo "Date is '$DATE'."
fi

如果$DATE不是%Y-%m-%d格式的有效日期,则此Perl oneliner将返回非零错误状态。

答案 1 :(得分:0)

awk way

awk 'split($0,a,"-"){print strftime("%d-%m-%Y",mktime(a[3]" "a[2]" "a[1]" 00 00 00"))==$0?"valid":"not valid"}' <<< "31-12-1992"

它将字符串转换为纪元,然后将纪元转换回原文。

编辑:

以为我会在测试这个作品后添加日期 来自01-01-0
31-12-2147483647

虽然缺点是在你低于1000年后,你必须从年份中删除前导零。

答案 2 :(得分:0)

您可以使用date实用程序验证日期,但首先必须将输入转换为可以理解的内容。我建议ISO表示(总是)。例如,它可能看起来像这样:

 #!/bin/sh

 PATTERN='\([0-9]\{1,2\}\)-\([0-9]\{1,2\}\)-\([0-9]\+\)'

 # if the pattern doesn't match, this will give date an empty string, so it will fail as expected.
 if date -d $(echo "$1" | sed -n "/$PATTERN/ { s/$PATTERN/\3-\2-\1/; p }") > /dev/null 2>&1 ; then
     echo valid
 else
     echo invalid
 fi

答案 3 :(得分:0)

如果您愿意将验证分为两个步骤,则可以相当轻松地完成此操作。首先,检查字符串的格式是否正确:

date=$1
[[ $date =~ ([0-9][0-9])-([0-9][0-9])-([0-9]+) ]] || { printf "Invalid date format\n"; exit 1; }

如果该测试通过,您可以提取日,月和年字段,然后验证每个字段是否在正确的范围内。

day=${BASH_REMATCH[1]}
month=${BASH_REMATCH[2]}
year=${BASH_REMATCH[3]}

thirty_one_days='0[1-9]|[12][0--9]|3[01]'
thirty_days='0[1-9]|[12][0--9]|30'
twenty_eight_days='0[1-9]|1[0-9]|2[0-8]'
case $month in
    01|03|05|07|08|10|12)
        [[ $day =~ $thirty_one_days ]] ;;
    04|06|09|11)
        [[ $day =~ $thirty_days ]] ;;
    02)
        # 1-28, but 29 OK in a leap year.
        [[ $day =~ $twenty_eight_days ]] ||
            (( year % 4 == 0 && $year % 400 == 0 && day == 29 ))
    *)
         false
 esac || { print "Invalid date\n"; exit 1; }