17

Linuxでbashシェルスクリプトを書いています。このプログラムは、日付(mm-dd-yyyy)をパラメーターとして受け入れます。日付が有効かどうかを確認する簡単な方法があるかどうか疑問に思っていますか?オペレーターはいますか?テストを使用して確認できますか?

4

8 に答える 8

21

で確認できますdate -d "datestring"

も有効ですが、ハイフンdate -d "12/31/2012"の使用は有効でdate -d "12-31-2012"はありませんdate

次の単語を使用することもできます:date -d 'yesterday'またはdate -d '1 week ago'両方とも有効です。

于 2012-05-25T17:59:53.117 に答える
11

入力日付値 MM-DD-YYYY から日、月、および年の値を抽出し、代わりに明確な (ISO) 形式 YYYY-MM-DD として検証できます (DD-MM-YYY 形式の日付を次のように検証できます)。日付を使用して「正しい」、たとえば 25-12-2010 ですが、有効な MM-DD-YYY 日付ではないため、最初に日付形式を変更する必要があります)


正しい形式の有効な日付で問題ありません

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 ではありません

DD-MM-YYYY 形式の 1979 年 4 月 20 日は、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
于 2013-01-10T11:05:55.303 に答える
8

スクリプトの使用については、できるだけシンプルにしました。日付関数で日付値をテストし、プロセスの終了コードをチェックします。

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

これにより、標準入力と標準エラーが null にリダイレクトされ、:echo を使用して終了コードが返さ$?れ、0 = 適切な日付と 1 = 不適切な日付を確認できます。

于 2015-08-20T11:27:35.937 に答える
4

以下は私にとってはうまくいきました。OSX ソリューションを提供してくれた同僚の Tyler Chamberlain に感謝します。

# 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 でテストしたところ、3 つのプラットフォームすべてで期待どおりに動作しました。Windows (Cygwin) でテストする時間がありませんでした。

于 2014-01-10T20:10:25.923 に答える
2

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

これが役立つことを願っています。

于 2012-05-25T18:04:50.760 に答える
1

strptime()Python のtimeまたはdatetimeモジュール、または Perl のTime::Pieceモジュールで利用可能な関数を使用できます。

于 2012-05-25T18:23:29.910 に答える