-1

I have used the method posted for the following question, but I still have some issues.

Validate date format in a shell script

$ ./check_date.sh 20190109
Input date format 20190109        # this should report error!

$ ./check_date.sh 2019-0109
[ERROR]: Invalid input date format 2019-0109

$ ./check_date.sh 2019-01-09
Input date format 2019-01-09

$ cat ./check_date.sh
#!/usr/bin/bash
date '+%Y-%m-%d' -d $1 > /dev/null 2>&1
if [ "$?" -ne 0 ]; then
    echo "[ERROR]: Invalid input date format $1"
    exit 1
else
    echo "Input date format $1"
fi

As you can see, I expect the input 20190109 will cause the script to report ERROR but instead it works without errors.

In summary, I need to validate the input date string so that it strictly follows the format YYYY-MM-DD.

Question> What should I do to get the script work as expected?

Thank you

5
  • 1
    Do you want to validate the format, or do you want to validate the format and the date? Commented Jan 10, 2019 at 15:29
  • It is best if I can validate both. Thank you! Commented Jan 10, 2019 at 15:30
  • 2
    You should send error messages to stderr: echo "[ERROR]: Invalid input date format $1" >&2 Commented Jan 10, 2019 at 15:35
  • 1
    The format option for the date command will not check / enforce the input date string in any way, it's used solely for formatting the output. A format like 20190109 is accepted by the date command as input to the the -d, --date=STRING switch so you won't be able to use this approach to validate your format requirement. Commented Jan 10, 2019 at 15:44
  • 1
    Also, just as a side note: the format does not need to be quoted if it has no spaces (since it's literal and won't change), however, it's better to quote the argument should a date string with spaces be passed in date +%Y-%m-%d -d "$1" Commented Jan 10, 2019 at 15:47

1 Answer 1

3

The following test should work:

if [[ "$1" =~ [0-9]{4}(-[0-9]{2}){2} ]] && date -d "$1" >/dev/null 2>&1; then
   success
else
   error
fi

It first checks if the format is correct NNNN-NN-NN, and then used date to check if the date is valid.

Why is your original code not working: You wrote:

date '+%Y-%m-%d' -d $1 > /dev/null 2>&1

You "assumed" that the string '+%Y-%m-%d' defined the input format, but it actually defines the output format. Date is capable to take a various collection of input strings and convert them accordingly:

$ date -d "yesterday" '+%F'
$ date -d "2019-01-01 + 10 days" '+%F'
$ date -d "5 fortnight ago" '+%F'
$ date -d "12/13/1099" '+%F'

You cannot force date to assume the input date string to have a given format.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.