Check If Argument Is a Valid Date in Bash Shell

check if argument is a valid date in bash shell

You can check with date -d "datestring"

So date -d "12/31/2012" is valid, but using hyphens, e.g. date -d "12-31-2012", is not valid for date.

You can also use words: date -d 'yesterday' or date -d '1 week ago' are both valid.

check if argument is a valid date time in shell script

You can get a bit creative since you have bash and map the date string into an array which can then be easily parsed with date -d (and the help of another associative array). Once the date/time is mapped to array elements and converted to seconds since epoch with date -d, you simply check the return of the date command to determine if the conversion succeeded or failed. Handle the return appropriately:

#!/bin/bash

[ -n "$1" ] || { ## validate one argument given
printf "error: insufficient input\nusage: %s dd-mmm-yy hh.mm.ss.ms\n" \
"${0##*/}"
exit 1
}

oifs="$IFS" ## save original Internal Field Separator
IFS=$' \t\n-.'; ## set IFS to break on - or .

dt=( $(echo $1) ) ## separate date into indexed array

[ "${#dt[@]}" -lt '7' ] && { ## check all 7 components present
printf "error: date doesn't match dd-mmm-yy hh.mm.ss.ms format\n"
exit 1
}

IFS="$oifs" ## reset original IFS

## create associative array mapping months to numerics
declare -A mo=(
[JAN]=1
[FEB]=2
[MAR]=3
[APR]=4
[MAY]=5
[JUN]=6
[JUL]=7
[AUG]=8
[SEP]=9
[OCT]=10
[NOV]=11
[DEC]=12
)

## any date after 30 considerd 1930, else considered 2000
[ "${dt[2]}" -gt '30' ] && dt[2]=$((${dt[2]} + 1000)) || \
dt[2]=$((${dt[2]} + 2000))

## use date to convert array contents to seconds since epoch
epochsec=$( date -d "${dt[2]}-${mo[${dt[1]}]}-${dt[0]} \
${dt[3]}:${dt[4]}:${dt[5]}.${dt[6]}" +%s )

if [ "$?" -ne '0' ]; then ## check if last return was error
printf "error: invalid date.\n"
else ## output good date
printf "date: %s\n" "$(date -d @$epochsec)"
fi

Example Use/Output

$ bash chkcustomdt.sh "08-FEB-18 11.45.18.844"
date: Thu Feb 8 11:45:18 CST 2018

There are a lot of ways to approach this, this was just the first that came to mind.

Validate date format in a shell script

Use date

date "+%d/%m/%Y" -d "09/99/2013" > /dev/null  2>&1
is_valid=$?

The date string must be in "MM/DD/YYYY" format.

If you do not get 0 then date is in invalid format.

Bash validate date

The BSD date that ships with Mac OS X doesn't support the -d option (or rather, it uses -d for something entirely different). Either install GNU date, or use the following to validate your input string:

date -f "%Y-%m-%d" -j "2012-02-29" >/dev/null 2>&1

The -f provides the input format, and the -j tells date to simply output the date, not attempt to set the system clock.

Test if variable is a date with the correct format

You can use this snippet:

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

Testing:

isValidDate "1900-12-25"
valid

isValidDate "1900-14-25"
invalid

isValidDate "01/01/1900"
invalid

Bash shell: How to check for specific date format?

regex is not the right tool to do the job.

e.g.

2013-02-29 (invalid date)
2012-02-29 (valid date)
2013-10-31 (valid date)
2013-09-31 (invalid date)
...

I would suggest passing the string to date -d, then check the return value. if return 0, everything is fine. if return 1, invalid date.

for example:

kent$  date -d "2012-02-29" > /dev/null 2>&1
kent$ echo $?
0

kent$ date -d "2013-02-29" > /dev/null 2>&1
kent$ echo $?
1

if you want to force the format is yyyy-mm-dd you can do both regex and date validation. regex only for the format, and date for the date validation.

because date -d accepts string like 02/27/2012 too.



Related Topics



Leave a reply



Submit