-1

In my bash script I want to check that date values provided via command line arguments by the user, have yyyy-mm-dd format. So for example, the date August 10th 2020 has to be written as 2020-08-10. Here is the test that I've written for pattern matching via a regular expression:

#!/usr/bin/bash

dateval="2020-08-10"
regexp="^[0-9]{4}-[0-9]{2}-[0-9]{2}$"

if [[ ! "${dateval}" =~ "${regexp}" ]]
then
    echo "Date format is not valid"
else
    echo "Date format is valid"
fi

This prints "Date format is not valid" and I don't understand why as the date value being tested is indeed in good format. Could you kindly make some clarification and indicated what I misunderstand?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
user17911
  • 1,073
  • 1
  • 8
  • 18
  • 2
    The regex should not be quoted so if [[ ! "${dateval}" =~ ${regexp} ]] should work – A.Hristov Aug 09 '20 at 18:15
  • 1
    Please paste your script first at [shellcheck.net](http://www.shellcheck.net/) and try to implement the recommendations made there. – Cyrus Aug 09 '20 at 18:16
  • @A.Hristov Thank you very much for your help. This solved the problem. How can I mark your answer as the solution to the question? It seems that I cannot do that by clicking beside your comment. – user17911 Aug 09 '20 at 18:25
  • @A.Hristov: No need to quote the LHS either: `[[ ! $dateval =~ $regexp ]]` works as well. – user1934428 Aug 10 '20 at 08:22

2 Answers2

1

Even after fixing the code issues, the regex approach would accept dates like 2020-13-99. I suggest a different approach. Replace:

if [[ ! "${dateval}" =~ "${regexp}" ]]

with:

if ! date -d "$dateval" +%F >/dev/null 2>&1

This will test if the date is actually parseable as a date. If will, for example, know that 2020-06-30 is valid but 2020-06-31 is invalid.

Limiting the acceptable date format

The above accepts any date that is valid and in a format date understands. If we want to require the yyyy-mm-dd format, then use:

if [ "$dateval" != "$(date -d "$dateval" +%F 2>/dev/null)" ]
John1024
  • 109,961
  • 14
  • 137
  • 171
  • 2
    Would still need some combination of regex or parameter expansion as the `date` test alone would accept, e.g. `6/30/2020` or `"next Tuesday"` or any of the other recognized formats instead of just `yyyy-mm-dd`. – David C. Rankin Aug 09 '20 at 18:37
  • @DavidC.Rankin. I thought that was a feature not a bug but you have a good point. If we do want to force the date format, we could use `[ "$dateval" != "$(date -d "$dateval" +%F 2>/dev/null)" ]` – John1024 Aug 09 '20 at 19:04
0

Thanks a lot to @A.Hristov for the help. In fact, the problem was the double quotes that I had put around the regular expression. So here is the correct version of the script which works as expected:

#!/usr/bin/bash
#
#
dateval="2020-08-10"
#
#
regexp="^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
#
#
if [[ ! "${dateval}" =~ ${regexp} ]]
then
    echo "Date format is not valid"
else
    echo "Date format is valid"
fi
user17911
  • 1,073
  • 1
  • 8
  • 18