有没有办法检查日期参数的格式是否正确(YYYY-MM-DD)?
我从网上得到了这个,但它对我不起作用:
date "+%Y-%m-%d" -d "2015-10-11" > /dev/null 2>&1
echo $?
我期待一个0
结果,但事实并非如此。有人可以用另一种方式告诉我吗?
答案1
bash
这将检查(使用内置正则表达式匹配)中的正确格式(YYYY-MM-DD) :
if [[ $1 =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]
then echo "Date $1 is in valid format (YYYY-MM-DD)"
else echo "Date $1 is in an invalid format (not YYYY-MM-DD)"
fi
跑步:
./script.sh 2015-12-10
输出:
Date 2015-12-10 is in valid format (YYYY-MM-DD)
它不检查日期本身是否有效,仅检查日期格式(如问题中所述,“检查日期参数的格式是否正确(YYYY-MM-DD”))
如果您需要检查日期格式和验证日期值,尝试如下:
if [[ $1 =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && date -d "$1" >/dev/null
then echo "Date $1 is valid and matches the format (YYYY-MM-DD)"
fi
这将丢弃通过正则表达式匹配的无效日期,例如 0000-88-77。
(此建议归功于@glenn jackman。)
答案2
您还没有标记操作系统,并且因为您正在使用ksh
我猜测您可能没有使用 Linux,并且您可能使用 Solaris。您给出的命令date
将起作用,但它适用于 GNU date
,其中-d
(或--date
) 是 GNU 增强功能。
因此,简单的选择是使用 GNU date
,您可能需要安装 GNU coreutils 软件包,或者您可能已经拥有它(/usr/sfw/bin
在 Solaris 上签入),它可能已经作为gdate
或提供gnudate
。这将正确验证 YYYY-MM-DD 格式的日期(与其他地方接受 2015-31-01 的正则表达式示例不同)
相反,您可以touch
在类似的情况下使用该命令更便携(POSIX)方式
touch -c -d 2015-12-12T00:00:00 /tmp/does-not-exist
- 使用
-c
这样就不会创建文件 - 将 T00:00:00 附加到日期以形成有效的时间戳
(但是,如果您使用 Solaris,不仅某些版本缺少-d
,我还发现某些版本至少有一个错误/错误功能,它们不验证而是试图变得聪明,因此“2015-02-29”变成“2015” -03-01”,没有错误,因此您不能使用这些版本进行日期验证。)
gawk
我更喜欢这种方式,假设你有(或者mawk
相反,但传统的nawk
缺乏这些时间功能),它是强大且便携的。
#!/usr/local/bin/gawk -f
BEGIN{
split(ARGV[1],bb,/-/)
tm=mktime( bb[1] " " bb[2] " " bb[3] " 00 00 00")
tms=sprintf("%04i-%02i-%02i",bb[1],bb[2],bb[3])
if (tms==strftime("%Y-%m-%d",tm)) exit 0
exit 1
}
以上
- 接受第一个参数并以“-”字符分割。
mktime()
确定指定 YYYY-MM-DD 的纪元时间戳sprintf()
标准化 YYYY-MM-DD(前导 0)strftime()
将纪元时间转换回 YYYY-MM-DD,并作为字符串进行比较
额外转换和比较的原因是为了捕获 C 库重新解释有问题的日期的情况mktime()
,就像 Linux 上的 glibc 的情况(与touch
上面的 Solaris 的问题相同)。
关心 YYYY-MM-DD 的正确格式可能也可能不意味着关心有效性日期(某事date
会做),甚至可能意味着能够消除YYYY-DD-MM 格式日期。如果您只想确认格式是“类似日期”,那么正则表达式就足够了:
grep -qE "^[0-9]{4}-[01]?[0-9]-[0123]?[0-9]$"
grep -qE "^[12][0-9]{3}-(0?[1-9]|10|11|12)-(0?[1-9]|[12][0-9]|3[01])$"
(在 Solaris 上/usr/xpg4/bin/grep
不使用默认值grep
)第一个将拒绝大多数虚假日期,第二个将拒绝几乎所有虚假日期。这样-q
就不会有任何输出,您可以按预期使用返回代码。请注意锚定 ( ^...$
) 或以其他方式限制正则表达式,使其不会简单地匹配有效子字符串,例如 2015-12-12345
答案3
您必须学习如何编写正则表达式来验证日期的格式是否正确。年-月-日
一种简单的方法是在一行中完成此操作,以便您可以使用日期和正则表达式并快速学习。
我将用来echo
生成日期,然后egrep
应用正则表达式并指示它是否找到匹配项。查看 的手册页egrep
,您会看到有一个-c
选项可以打印匹配项计数,因为您只发送一个日期,计数将为 0 或 1,具体取决于是否找到匹配项。
这是你可以玩的一个衬垫。
echo 0000-00-00 |egrep -c -e 'regular-expression-in-here'
插入正则表达式(您可以从美联社在他们的答案中给了你)看看它的效果如何。更改日期并查看其有效性。这是另一张,略有不同。
[0-9]{4}-[0-1][0-9]-[0-3][0-9]
答案4
您可以简单地比较date
日期的输出是否与原始值匹配:
d="2015-10-11"
if [ "`date '+%Y-%m-%d' -d $d 2>/dev/null`" = "$d" ]
then
echo $d is a valid YYYY-MM-DD date
else
echo $d is NOT a valid YYYY-MM-DD date
fi