date -d无法识别格式%d-%m-%Y

时间:2018-05-26 16:22:50

标签: linux bash shell date

我的脚本应该接受4种日期格式:yyyy-mm-dd,yyyy / mm / dd,dd-mm-yyyy,dd / mm / yyyy。

要检查用户提供的日期d是否有效,请执行以下任何一种格式:

    if [ "`date '+%Y-%m-%d' -d $d 2>/dev/null`" == "$d" ]
      then
        echo "1"
    elif [ "`date '+%d-%m-%Y' -d $d 2>/dev/null`" == "$d" ]
      then
        echo "2"
    elif [ "`date '+%Y/%m/%d' -d $d 2>/dev/null`" == "$d" ]
      then
        echo "3"
    elif [ "`date '+%d/%m/%Y' -d $d 2>/dev/null`" == "$d" ]
      then
        echo "4"
    else
        echo `date '+%d-%m-%Y' -d $d`
        echo "other"
    fi

如果我将d设置为2018-01-01,2018 / 01/01或01/01/2018,我会得到预期的输出(分别为1,3和4)。

但是,如果我使用01-01-2018,则输出为:

date: invalid date `01-01-2018'

other

原因是什么?

2 个答案:

答案 0 :(得分:3)

GNU date中,+format说明符表示所需的输出格式,而不是如何解析-d选项的参数。

BSD date允许您使用-f指定输入格式,但我猜您使用的是Linux。)

为了猜测输入格式,我建议像

case $d in
    [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])
      # assume yyyy-mm-dd
      ;;
    [0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9])
      # in the civilized world, assume dd/mm/yyyy
      # in the US, assume mm/dd/yyyy
      # in the general case, assume nothing; give up
      ;;
    ... etc ...
esac

请注意,实际上没有办法知道4/3代表3月4日或4月3日。要求用户使用明确的格式,或明确指出如何解释格式,是唯一合理的解决方案。

date命令的功能与您正在使用的shell无关。

答案 1 :(得分:1)

这是因为date认为有效的数字日期字符串格式非常有限。根据{{​​3}},格式"日 - 月 - 年"未包含在接受的格式中( 29.2 ):

对于数字月份,允许使用ISO 8601格式“年 - 月 - 日”,其中年份为任意正数,月份为01到12之间的数字,而日期为01到31之间的数字。如果数字小于10,则必须存在前导零。如果年份为68或更小,则增加2000;否则,如果年份小于100,则添加1900。在美国流行的建筑“月/日/年”被接受。也是'月/日',省略年份。

我认为在bash脚本中实现变通方法并不困难。