I am trying to validate the date entered by the user(mmddyyyy),used the below but its not working, please correct me where i am wrong.

 date  "+%m%d%Y" -d "02012019" > /dev/null  2>&1
        echo $?
  • How does the user enter the date? by a simple read command? Feb 15 at 17:19
  • via command line he will pass ,ex: sh xx.sh -f 02122029
    – Renga
    Feb 15 at 17:23
  • 1
    I don't think it's possible to use date in that way (at least, not the GNU implementation) - it parses the string given via -d using its own built-in rules, then if successful outputs the resulting date in the specified format. AFAIK it does not attempt to use the output format to parse strings given as an inputs via -d (as, for example, strptime would). Feb 15 at 17:23
  • 1
    @Renga in your comment you use sh. The script must be interpreted by /bin/sh, or could be /bin/bash? Feb 15 at 18:05
  • 1
    Also the point that the user can enter the input date in several alternative valid formats, like @1613412105 or 'now + 23 days' or 'last tuesday', which all return a zero status. Feb 15 at 18:09

With zsh:

#! /bin/zsh -
date=${1?No date specified}

zmodload zsh/datetime || exit
  strftime -rs t %m%d%Y "$date" 2> /dev/null &&
  strftime -s canonical_date_for_t %m%d%Y "$t" 2> /dev/null &&
  [[ $date = $canonical_date_for_t ]]
  print -r -- $date is valid
  print -ru2 -- ${(q+)date} is invalid
  exit 1

strftime -r calls strptime() which parses the input $date according to %m%d%Y. While strftime without -r converts back to a %m%d%Y formatted date using strftime().

strptime() would accept a 02292019 (and treat it like 03012019), but once converted back with strftime(), that becomes 03012019 so would be rejected. Similarly 12310001 (0001-12-31) would be rejected as 12311 would be expected instead (%Y for year 1 AC is 1, not 0001; replace %Y with %4Y in the second strftime invocation, if you'd rather 0001 be the expected representation of year 1).


If I understand you correctly, this is a possible approach:



[[ ! "$d" =~ ^[0-9]{8}$ ]] && \
  echo "Illegal number of characters, or not numbers." && \


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

[ $? -ne 0 ] && echo "Invalid date." || echo "Valid date."

$ ./xx.sh 0201201x
Illegal number of characters, or not numbers.
$ ./xx.sh 0201201900000
Illegal number of characters, or not numbers.
$ ./xx.sh 32022019
Invalid date
$ ./xx.sh 02022019
Valid date.

Now 01022019 would be a valid date, but if the user typed the day first and then the month, you would need another set of validations for your specific needs.

  • Thanks alot,i just edited the parsing section(d="${d:4}${d:0:2}${d:2:2}") and working fine .
    – Renga
    Feb 15 at 18:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.