检查日期参数是否采用 yyyy-mm-dd 格式

检查日期参数是否采用 yyyy-mm-dd 格式

有没有办法检查日期参数的格式是否正确(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

相关内容