检查参数是bash shell的有效日期(check if argument is a valid

2019-07-29 13:48发布

我在Linux中写一个bash shell脚本,这个程序将接受一个日期(MM-DD-YYYY)作为参数。 我想知道如果有一个简单的方法来检查,如果日期是有效的? 有运营商,我可以只使用测试,以检查?

Answer 1:

您可以检查date -d "datestring"

所以date -d "12/31/2012"是有效的,但使用连字符,如date -d "12-31-2012" ,是无效的date

你也可以用四个字: date -d 'yesterday'date -d '1 week ago'都是有效的。



Answer 2:

您可以从输入日期值MM-DD-YYYY提取日,月,年值和验证它作为明确的(ISO)格式YYYY-MM-DD,而不是(你可以验证DD-MM-YYY格式的日期“正确”使用日期,例如25-12-2010,但它不是一个有效的MM-DD-YYY日期,因此需要先更改日期格式)


以正确的格式的有效日期是OK

2005年11月30日是有效的:

$ 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

以正确的格式无效的日期不OK

2005年11月31日不验证:

$ 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

格式不正确的有效日期不OK

1979年4月20日在DD-MM-YYYY格式不确认为MM-DD-YYYY日期:

$ 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

替代简单的方法:使用bash变量字符串替换连字符斜线

$ 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


Answer 3:

对于脚本中使用,我一直是这么简单,我可以。 测试与当时的日期函数检查进程的退出代码中的日期值。

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

这将重定向标准和标准差为null :使用回声返回退出代码$? 让我来检查0 =好日期和1 =劣枣。



Answer 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的)。



Answer 5:

case语句可以很容易地支持多种格式和拍摄日期部分,即

 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

我希望这有帮助。



Answer 6:

你可以使用strptime()在Python的可用功能的时间或日期时间模块或Perl的时间::件模块。



Answer 7:

对于YYYY-MM-DD(ISO 8601)的确认日期在OSX bash shell中,使用以下方法验证的格式和日期。

isYYYYMMDDdate() {
  [[ "$1" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && [[ "$1" == $(date -r $(date -j -f "%Y-%m-%d" "$1" "+%s") '+%Y-%m-%d') ]] &> /dev/null; echo "$?"
}
  1. 它首先使用正则表达式匹配检查格式。
  2. 然后,将其转换为划时代的时间,然后回到一个日期。
  3. 如果原始和两次转换日期匹配,那么它是有效的。

测试有效日期:2005-11-30

$ isYYYYMMDDdate 2005-11-30
0

测试无效日期:2005年11月31日

$ isYYYYMMDDdate 2005-11-31
1

测试有效日期格式不正确:1979-20-04

$ isYYYYMMDDdate 1979-20-04
1


文章来源: check if argument is a valid date in bash shell
标签: linux bash shell