Validate date format in a shell script

2019-01-06 21:37发布

问题:

I have to create a Shell Script wherein one of the parameters will be the date in the format dd/mm/yyyy. My question is, how can I check if the Date passed as parameter really follows this Date Format? I tried to use the grep command as below:

if echo "$1" | grep -q '^[0-3][0-9]/[0-1][0-9]/[0-9]\{4\}$'

but it didn't give the correct format because the day for example can be 33, 34, (...), that is not really the correct format. Anyone know something that can really check if the date passed really follows the format dd/mm/yyyy ?

回答1:

Use date

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

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



回答2:

The simplest solution, that still works perfectly, is the following :

if [[ $1 =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && date -d "$1" >/dev/null 2>&1
   ...

It consists in combining 2 checks :

  • the first part checks that $1 is of this format : NNNN-NN-NN
  • the second part checks that it is a valid date

You need the two checks because :

  • if you don't do the first check, date will exit with code 0 even if your variable is a valid date in another format
  • if you don't do the second check, then you can end up with a 0 even for variables such as 2016-13-45


回答3:

First, check the form of the input using the regex. Then use awk to switch to mm/dd/yyyy and use date to validate. You can use the following expression in your if statement:

echo "$1" | egrep -q '^[0-3][0-9]/[0-1][0-9]/[0-9]{4}$' && date -d "$(echo "$1" | awk 'BEGIN{FS=OFS="/"}{print $2"/"$1"/"$3}')" >/dev/null 2>&1


回答4:

Simplest way for dd/mm/yyyy exactly in Bash is:

if [[ $1 == [0-3][0-9]/[0-1][0-9]/[0-9][0-9][0-9][0-9] ]]

Or

if [[ $1 =~ ^[0-3][0-9]/[0-1][0-9]/[0-9]{4}$ ]]


回答5:

How about using awk:

echo "31/12/1999" | awk  -F '/' '{ print ($1 <= 31 && $2 <= 12 && match($3, /^[1-9][1-9][1-9][1-9]$/)) ? "good" : "bad" }'

It prints "good" if its valid date else prints "bad"



回答6:

#! /bin/bash

isDateInvalid()
{
    DATE="${1}"

    # Autorized separator char ['space', '/', '.', '_', '-']
    SEPAR="([ \/._-])?"

    # Date format day[01..31], month[01,03,05,07,08,10,12], year[1900..2099]
    DATE_1="((([123][0]|[012][1-9])|3[1])${SEPAR}(0[13578]|1[02])${SEPAR}(19|20)[0-9][0-9])"

    # Date format day[01..30], month[04,06,09,11], year[1900..2099]
    DATE_2="(([123][0]|[012][1-9])${SEPAR}(0[469]|11)${SEPAR}(19|20)[0-9][0-9])"

    # Date format day[01..28], month[02], year[1900..2099]
    DATE_3="(([12][0]|[01][1-9]|2[1-8])${SEPAR}02${SEPAR}(19|20)[0-9][0-9])"

    # Date format day[29], month[02], year[1904..2096]
    DATE_4="(29${SEPAR}02${SEPAR}(19|20(0[48]|[2468][048]|[13579][26])))"

    # Match the date in the Regex

    if ! [[ "${DATE}" =~ "^(${DATE_1}|${DATE_2}|${DATE_3}|${DATE_4})$" ]]
    then
        echo -e "ERROR - '${DATE}' invalid!"
    else
        echo "${DATE} is valid"
    fi
}

echo
echo "Exp 1: "`isDateInvalid '12/13/3000'`
echo "Exp 2: "`isDateInvalid '12/11/2014'`
echo "Exp 3: "`isDateInvalid '12 01 2000'`
echo "Exp 4: "`isDateInvalid '28-02-2014'`
echo "Exp 5: "`isDateInvalid '12_02_2002'` 
echo "Exp 6: "`isDateInvalid '12.10.2099'`
echo "Exp 7: "`isDateInvalid '31/11/2000'`


回答7:

Here's a function to do some data validation this:

# Script expecting a Date parameter in MM-DD-YYYY format as input
verifyInputDate(){
    echo ${date} | grep '^[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]$'
    if [ $? -eq 0 ]; then
         echo "Date is valid"
     else
          echo "Date is not valid"
     fi
}


回答8:

`X="2016-04-21" then check for the below value being 1 or 0.

cal echo $x | cut -c 6-7 echo $x | cut -c 1-4 2>/dev/null | grep -c echo $x | cut -c 9-10

If the value is 1, then it's valid, else it's not valid.



回答9:

This function expects 2 strings,a format string, a date string

The format string uses the codes from the date command but does not include the '+'

The function returns 0 if the provided date matches the given format, otherwise it returns 1

datecheck() {
    local format="$1" d="$2"
    [[ "$(date "+$format" -d "$d" 2>/dev/null)" == "$d" ]]
}


回答10:

I wrote this bash script to validate date. I can accept mont as alphanumeric.

#!/bin/bash

function isDateValid {
    DATE=$1

    if [[ $DATE =~ ^[0-9]{1,2}-[0-9a-zA-Z]{1,3}-[0-9]{4}$ ]]; then
        echo "Date $DATE is a number!"
        day=`echo $DATE | cut -d'-' -f1`
        month=`echo $DATE | cut -d'-' -f2`
        year=`echo $DATE | cut -d'-' -f3`

                if [ "$month" == "01" ] || [ "$month" == "1" ]; then
                        month="Jan"
                elif [ "$month" == "02" ] || [ "$month" == "2" ]; then
                        month="Feb"
                elif [ "$month" == "03" ] || [ "$month" == "3" ]; then
                        month="Mar"
                elif [ "$month" == "04" ] || [ "$month" == "4" ]; then
                        month="Apr"
                elif [ "$month" == "05" ] || [ "$month" == "5" ]; then
                        month="May"
                elif [ "$month" == "06" ] || [ "$month" == "6" ]; then
                        month="Jun"
                elif [ "$month" == "07" ] || [ "$month" == "7" ]; then
                        month="Jul"
                elif [ "$month" == "08" ] || [ "$month" == "8" ]; then
                        month="Aug"
                elif [ "$month" == "09" ] || [ "$month" == "9" ]; then
                        month="Sep"
                elif [ "$month" == "10" ]; then
                        month="Oct"
                elif [ "$month" == "11" ]; then
                        month="Nov"
                elif [ "$month" == "12" ]; then
                        month="Dec"
                fi

        ymd=$year"-"$month"-"$day
        echo "ymd: "$ymd
        dmy=$(echo "$ymd" | awk -F- '{ OFS=FS; print $3,$2,$1 }')
        echo "dmy: "$dmy
        if date --date "$dmy" >/dev/null 2>&1; then
                echo "OK"
            return 0
        else
                echo "NOK"
            return 1
        fi
    else
        echo "Date $DATE is not a number"
        return 1
    fi
}


if isDateValid "15-15-2014"; then
    echo "date is valid =)"
else
    echo "bad format date"
fi
echo "==================="
if isDateValid "15-12-2014"; then
        echo "date is valid =)"
else
        echo "bad format date"
fi
echo "==================="
if isDateValid "15-Dec-2014"; then
        echo "date is valid =)"
else
        echo "bad format date"
fi
echo "==================="
if isDateValid "1-May-2014"; then
        echo "date is valid =)"
else
        echo "bad format date"
fi
echo "==================="
if isDateValid "1-1-2014"; then
        echo "date is valid =)"
else
        echo "bad format date"
fi
echo "==================="
if isDateValid "12-12-2014"; then
        echo "date is valid =)"
else
        echo "bad format date"
fi


回答11:

Blockquote

DATE = "$*"

[[ "${DATE}" != @(((([123][0]|[012][1-9])|3[1])?([ \/._-])(0[13578]|1[02])?([ \/._-])(19|20)[0-9][0-9])|(([123][0]|[012][1-9])?([ \/._-])\
(0[469]|11)?([ \/._-])(19|20)[0-9][0-9])|(([12][0]|[01][1-9]|2[1-8])?([ \/._-])02?([ \/._-])(19|20)[0-9][0-9])|(29?([ \/._-])02?([ \/._-])\
(19|20(0[48]|[2468][048]|[13579][26])))) ]] && echo error || echo good)