Вопрос по bash, shell, linux – проверьте, является ли аргумент верной датой в оболочке bash

10

Я пишу скрипт оболочки bash в Linux, эта программа примет дату (mm-dd-yyyy) в качестве параметра. Мне интересно, есть ли простой способ проверить, является ли дата действительной? есть ли оператор, и я могу просто использовать тест для проверки?

Попробуйтеdate полезность. 0xC0000022L
Обязательно:ISO 8601 Marco

Ваш Ответ

6   ответов
10

месяца и года из значения даты ввода MM-DD-YYYY и проверить его как однозначный (ISO) формат YYYY-MM-DD вместо этого (вы можете проверить дату в формате DD-MM-YYY как & quot; исправить & quot; использовать дату, например, 25-12-2010, но она не является действительной датой MM-DD-YYY, поэтому сначала необходимо изменить формат даты)

A valid date in the correct format is OK

30 ноября 2005 года действует:

$ DATE=11-30-2005; d=${DATE:3:2}; m=${DATE:0:2}; Y=${DATE:6:4}; echo "year=$Y, month=$m, day=$d"; if date -d "$Y-$m-$d" &> /dev/null; then echo VALID; else echo INVALID; fi
year=2005, month=11, day=30  
VALID

$ DATE=11-30-2005; if date -d "${DATE:6:4}-${DATE:0:2}-${DATE:3:2}" &> /dev/null; then echo VALID; else echo INVALID; fi
VALID
An invalid date in the correct format is NOT OK

31 ноября 2005 года не действует:

$ DATE=11-31-2005; d=${DATE:3:2}; m=${DATE:0:2}; Y=${DATE:6:4}; echo "year=$Y, month=$m, day=$d"; if date -d "$Y-$m-$d" &> /dev/null; then echo VALID; else echo INVALID; fi
year=2005, month=11, day=31  
INVALID

$ DATE=11-31-2005; if date -d "${DATE:6:4}-${DATE:0:2}-${DATE:3:2}" &> /dev/null; then echo VALID; else echo INVALID; fi
INVALID
A valid date in the incorrect format is NOT OK

20 апреля 1979 года в формате ДД-ММ-ГГГГ не считается датой ММ-ДД-ГГГГ:

$ DATE=20-04-1979; d=${DATE:3:2}; m=${DATE:0:2}; Y=${DATE:6:4}; echo "year=$Y, month=$m, day=$d"; if date -d "$Y-$m-$d" &> /dev/null; then echo VALID; else echo INVALID; fi
year=1979, month=20, day=04  
INVALID

$ DATE=20-04-1979; if date -d "${DATE:6:4}-${DATE:0:2}-${DATE:3:2}" &> /dev/null; then echo VALID; else echo INVALID; fi
INVALID
Alternate simpler method: use BASH variable string replace hyphens to slashes
$ DATE="04-30-2005"; [[ $(date -d "${DATE//-/\/}" 2> /dev/null) ]] && echo VALID || echo INVALID
VALID

$ DATE="04-31-2005"; [[ $(date -d "${DATE//-/\/}" 2> /dev/null) ]] && echo VALID || echo INVALID
INVALID
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededthenError: User Rate Limit ExceededelseError: User Rate Limit ExceededDATE=20-04-1979; d=${DATE:3:2}; m=${DATE:0:2}; Y=${DATE:6:4}; echo "year=$Y, month=$m, day=$d"; if ! date -d "$Y-$m-$d" &> /dev/null; then echo INVALID; fi
4

леру Чемберлену за решение OSX.

# Validate a given date/time in Bash on either Linux or Mac (OSX).

# Expected date/time format (in quotes from the command line):  YYYY-MM-DD HH:MM:SS
# Example(s):  ./this_script "2012-02-29 13:00:00"   # IS valid
#              ./this_script "2013-02-29 13:00:00"   # Is NOT valid

START_DATETIME=$1

function report_error_and_exit
{
   local MSG=$1
   echo "$MSG" >&2
   exit 1
}

# We can use OSTYPE to determine what OS we're running on.
# From http://stackoverflow.com/questions/394230/detect-the-os-from-a-bash-script

# Determine whether the given START_DATETIME is valid.
if [[ "$OSTYPE" == "linux-gnu" ]]
then
   # Validate the date on a Linux machine (Redhat or Debian).  On Linux, this is 
   # as easy as adding one minute and checking the return code.  If one minute 
   # cannot be added, then the starting value is not a valid date/time.
   date -d "$START_DATETIME UTC + 1 min" +"%F %T" &> /dev/null
   test $? -eq 0 || report_error_and_exit "'$START_DATETIME' is not a valid date/time value. $OSTYPE"
elif [[ "$OSTYPE" == "darwin"* ]]
then
   # Validate the date on a Mac (OSX).  This is done by adding and subtracting
   # one minute from the given date/time.  If the resulting date/time string is identical 
   # to the given date/time string, then the given date/time is valid.  If not, then the
   # given date/time is invalid.
   TEST_DATETIME=$(date -v+1M -v-1M -jf "%F %T" "$START_DATETIME" +"%F %T" 2> /dev/null)

   if [[ "$TEST_DATETIME" != "$START_DATETIME" ]]
   then
      report_error_and_exit "'$START_DATETIME' is not a valid date/time value. $OSTYPE"
   fi
fi

echo "The date/time is valid."

Я протестировал этот сценарий в системе на базе Red Hat, системе на основе Debian и OSX, и он работал, как и ожидалось, на всех трех платформах. Я не успел протестировать на Windows (Cygwin).

1

strptime() функция доступна в Pythonвремя или жеДата и время модули или PerlВремя :: Кусок модуль.

13

date -d "datestring"

такdate -d "12/07/2012" допустимо, но использование дефиса недопустимо для bash.

Вы также можете использовать слова:date -d 'yesterday' или жеdate -d '1 week ago' оба действительны.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededdateError: User Rate Limit Exceeded
2

тывать части даты, т.е.

 case ${date} in
    [0-3][0-9]-[0-1][0-9]-[0-9][0-9][0-9][0-9] )
       yr=...
       mn=...
       dy=... 
    ;;
    [0-1][0-9]-[0-3][0-9]-[0-9][0-9][0-9][0-9] )
       yr=...
       ,dy=... 
       mn=...
    ;;
    .... other formats
    ;;
    * )
      echo "ERROR on date format, from value=$date, expected formats ..."
      return 1
    ;;     
 esac

Надеюсь, это поможет.

7

насколько мог. Проверка значения даты с помощью функции даты, а затем проверка кода выхода процесса.

date -d "02/01/2000" 2>: 1>:; echo $?

Это перенаправит стандартную и стандартную ошибку на ноль: и используя echo для возврата кода выхода с$? позволяет мне проверить 0 = хорошая дата и 1 = плохая дата.

Похожие вопросы