Shell中的日期验证


14

我想在shell脚本中验证以下日期格式

2015-Jul-13

我正在使用,date -d "2015-Jul-13" +"%Y-%b-%d"但是它给了错误

date: invalid date '2015-Jul-13'

@Pandya:OP对他/她的问题很清楚。OP希望验证(检查输入的日期是否有效)所提及的日期格式,但表示输入的日期无效。
2015年

GNU date无法识别YYYY-MMM-DD。您可以使用YYYY-MM-DD还是DD MMM YYYY代替?
roaima

我非常确定at这样做,而且-我认为- touch也是如此。我写了touch一次基于日期验证的外壳函数...不,不是touch-它只处理数字,但at会进行一些相当深的解析...
mikeserv

@Thushi让我们清除我们的多余评论
Pandya

6
误读了标题:日期验证很糟糕
Adam Davis

Answers:


12

GNU date不支持YYYY-MMM-DD。但是,它确实了解DD-MMM-YYYY。因此,如果您真的必须处理这种格式的日期,则可以使用类似的方法来完成,只需将参数交换为date期望的格式即可:

ymd='2015-Jul-13'

dmy=$(echo "$ymd" | awk -F- '{ OFS=FS; print $3,$2,$1 }')
if date --date "$dmy" >/dev/null 2>&1
then
    echo OK
fi

这是一个全壳解决方案。将其分解后,IFS=-指令告诉外壳程序用连字符(-而不是空格)分隔即将出现的命令行。的set $ymd解析$ymd变量作为一个命令行,但现在由连字符分割,分配值的参数$1$2 及以下。在echo "$3-$2-$1"平凡输出以相反的顺序三个捕获的值。

ymd='2015-Jul-13'

dmy=$(IFS=-; set $ymd; echo "$3-$2-$1")
if date --date "$dmy" >/dev/null 2>&1
then
    echo OK
fi

@mikeserv:太酷了!它适用于: ymd=$(IFS=-;set $ymd; echo "$3-$2-$1") 您能否揭示set命令背后的魔力?
2015年

11

从联机帮助页:-

DATE STRING
       The --date=STRING is a mostly free format human readable date string such as "Sun, 29 Feb 2004 16:21:42 -0800"
       or  "2004-02-29  16:21:42" or even "next Thursday".  A date string may contain items indicating calendar date,
       time of day, time zone, day of week, relative time, relative date, and numbers.  An empty string indicates the
       beginning  of  the  day.   The  date string format is more complex than is easily documented here but is fully
       described in the info documentation.

但似乎无法识别YYYY-MMM-DD格式。因此,您可以从下面或类似的方式使用:

$ date -d "2015-07-13" +"%Y-%b-%d"
2015-Jul-13
$ date -d "Jul 13 2015" +"%Y-%b-%d"
2015-Jul-13
$ date -d "13 Jul 2015" +"%Y-%b-%d"
2015-Jul-13

否则,您必须先将其转换/ 重组,然后再发送给date

另请参阅如何为迄今为止的输入指定格式?


我建议访问:日期输入格式

这是规则。

对于数字月份,允许使用ISO 8601格式“ year-month-day”,其中year是任意正数,month是介于01和12之间的数字,而day是介于01和31之间的数字。必须存在前导零。如果数字小于十。如果年份是68或更短,则将2000加上;否则,如果年份小于100,则将1900添加到其中。接受在美国流行的“月/日/年”构造。也是“月/日”,省略了年份。

字面意思的月份可以完整说明:“ 1月”,“ 2月”,“ 3月”,“ 4月”,“ 5月”,“ 6月”,“ 7月”,“ 8月”,“ 9月”,“ 10月”,“ 11月”或“ 12月”。文字月份可以缩写为前三个字母,后面可以跟一个缩写点。也可以写“ Sept”而不是“ September”。

如果逐字写成月份,则日历日期可以采用以下任意一种形式:

 日月年
 日日月
 月日日年
 日月日年

我强调

在这里,您可以看到没有像year-month-day这样的格式!(连续几个月都是字面上的意思)


7

有了zsh您可以使用strftime内置的(通过提供zsh/datetime)与-r(反向):

strftime -r 格式时间字符串

它使用format解析时间字符串并输出自纪元以来的秒数:

zmodload zsh/datetime
strftime -r %Y-%b-%d 2015-Jul-13
1436734800

如果日期无效,则会出错:

strftime -r %Y-%b-%d 2015-Jul-33
zsh:strftime:5:格式不匹配

您还可以将自纪元以来的秒数转换为任何其他标准/自定义日期格式,例如

strftime '%A, %B %d, %Y' 1447970400
2015年11月20日,星期五
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.