bash 在unix中验证DD-MM-YYYY格式的日期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27380025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
validate date in unix for DD-MM-YYYY format
提问by Rubab
How to validate the date in Unix
.
Where the date format is DD-MM-YYYY
.
For example if i run one script ./ValidateDate.sh DD-MM-YYYY
then it should check that the date is in this format and also that the date exists.
If date is valid and in above format then proceed for next else print message 'Invalid date'
如何验证Unix
.
日期格式在哪里DD-MM-YYYY
。
例如,如果我运行一个脚本,./ValidateDate.sh DD-MM-YYYY
那么它应该检查日期是否采用这种格式以及日期是否存在。
如果日期有效且采用上述格式,则继续下一个其他打印消息“无效日期”
Thanks.
谢谢。
回答by David W.
Well... This is a fine can o' worms.
嗯...这是一个很好的蠕虫。
Any shell script that you create may not work on all of the various flavors of Unix/Linux.
您创建的任何 shell 脚本可能无法在所有不同的 Unix/Linux 版本上运行。
The BSD date command (found on OS X and Solaris) does a great job at taking in the date and verifying the format. It requires you to specify your date format, but once you do, it has no problems:
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 and other systems that use GNU's date can also validate the date, but use a different syntax:
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
I say With a bit of luckbecause it's up to the date
command to figure out your date's format. This normally works, and will work with your YYYY-MM-DD
format, but it can be confusing:
我说有点运气,因为这取决于date
确定日期格式的命令。这通常有效,并且适用于您的YYYY-MM-DD
格式,但可能会令人困惑:
Imagine this:
想象一下:
$ DATE="15/6/2014" # It's June 15, 2014
$ date -d "$DATE"
date: invalid date `15/6/2014' # Invalid?
That's because in my timezone, the dd/mm/yyyy
format isn't a valid format. In my timezone, the date should be mm/dd/yyyy
. To get around this you can use Wintermute'ssuggestion and format the date into ISO format before using GNU's date format.
那是因为在我的时区,dd/mm/yyyy
格式不是有效格式。在我的时区,日期应该是mm/dd/yyyy
. 为了解决这个问题,您可以使用Wintermute 的建议并将日期格式化为 ISO 格式,然后再使用 GNU 的日期格式。
A more universalpossibility is to use Perl or Python to figure out if the date is correct:
更普遍的可能性是使用 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
This Perl oneliner will return a non-zero error status if $DATE
isn't a valid date in %Y-%m-%d
format.
如果格式$DATE
不是有效日期,则此 Perl oneliner 将返回非零错误状态%Y-%m-%d
。
回答by David W.
awk way
awk 方式
awk 'split( #!/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 "" | sed -n "/$PATTERN/ { s/$PATTERN/--/; p }") > /dev/null 2>&1 ; then
echo valid
else
echo invalid
fi
,a,"-"){print strftime("%d-%m-%Y",mktime(a[3]" "a[2]" "a[1]" 00 00 00"))==date=
[[ $date =~ ([0-9][0-9])-([0-9][0-9])-([0-9]+) ]] || { printf "Invalid date format\n"; exit 1; }
?"valid":"not valid"}' <<< "31-12-1992"
It Converts the string to epoch,converts epoch back then checks against the original.
它将字符串转换为纪元,将纪元转换回来然后检查原始文件。
Edit:
编辑:
Thought i would add after testing this works for dates
FROM 01-01-0
TO 31-12-2147483647
以为我会在测试此日期后添加
从01-01-0
到31-12-2147483647
Although a drawback is after you go below the year 1000 you have to remove leading zeros from the year.
尽管缺点是在低于 1000 年之后,您必须从年份中删除前导零。
回答by Wintermute
You can validate the date with the date
utility, but you first have to transform the input into something it can understand. I suggest ISO representation (always). It could, for example, look like this:
您可以使用该date
实用程序验证日期,但首先必须将输入转换为它可以理解的内容。我建议 ISO 代表(总是)。例如,它可能如下所示:
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; }
回答by chepner
You can do this fairly easily if you are willing to break the validation into two steps. First, check that the string is in the right format:
如果您愿意将验证分为两个步骤,您可以很容易地做到这一点。首先,检查字符串的格式是否正确:
##代码##If that test passes, you can extract the day, month, and year fields, then verify that each falls in the correct range.
如果该测试通过,您可以提取日、月和年字段,然后验证每个字段是否都在正确的范围内。
##代码##