web-dev-qa-db-ja.com

日付引数がyyyy-mm-dd形式であるかどうかを確認します

日付引数が正しい形式(YYYY-MM-DD)であるかどうかを確認する方法はありますか?

私はこれをウェブから入手しましたが、私にとってはうまくいきません:

date "+%Y-%m-%d" -d "2015-10-11" > /dev/null  2>&1
echo $?

0の結果を期待していますが、そうではありません。誰かが別の方法を言うことができますか?

4
louggle

これは、bashの正しい形式(YYYY-MM-DD)をチェックします(組み込みの正規表現一致で)。

_if [[ $1 =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]
  then echo "Date $1 is in valid format (YYYY-MM-DD)"
  else echo "Date $1 is in an invalid format (not YYYY-MM-DD)"
fi
_

実行:

_./script.sh 2015-12-10_

出力:

Date 2015-12-10 is in valid format (YYYY-MM-DD)

formatのみが日付自体が有効かどうかをチェックしません(質問に記載されているように、「日付引数が正しい形式(YYYY-MM-DD)かどうかをチェックします」)

日付の形式を確認して日付の値を検証する必要がある場合は、次のようにします。

_if [[ $1 =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && date -d "$1" >/dev/null
      then echo "Date $1 is valid and matches the format (YYYY-MM-DD)"
fi
_

これにより、正規表現マッチングに合格した0000-88-77のような無効な日付が破棄されます。

(クレジットはこの提案のために@glenn jackmanに送られます。)

8
A.P.

日付が正しい形式であることを検証するための正規表現の書き方を学ぶ必要があります。 yyyy-mm-dd

簡単な方法は、これを1行で行うことです。これにより、日付と正規表現をいじって、すばやく学習できます。

echoを使用して日付を生成し、次にegrepを使用して正規表現を適用し、一致が見つかったかどうかを示します。 egrepのマニュアルページを見てください。-cオプション。一致の数を出力します。送信するのは1つの日付だけなので、一致が見つかったかどうかによって、カウントは0または1になります。

これがあなたと遊ぶためのあなたのワンライナーです。

echo 0000-00-00 |egrep -c -e 'regular-expression-in-here'

正規表現を挿入して( A.P で始めることができます)、それがどのように機能するかを確認します。日付を変更し、検証する内容を確認します。ここに別のものがありますが、少し異なります。

[0-9]{4}-[0-1][0-9]-[0-3][0-9]

0
X Tian

日付のdate出力が元の値と一致するかどうかを単純に比較できます。

d="2015-10-11"
if [ "`date '+%Y-%m-%d' -d $d 2>/dev/null`" = "$d" ]
then
  echo $d is a valid YYYY-MM-DD date
else
  echo $d is NOT a valid YYYY-MM-DD date
fi
0

OSにタグを付けていませんが、kshを使用しているため、おそらくLinuxを使用していないと思いますが、mightSolarisを使用している。指定したdateコマンドは機能しますが、GNU date用です。ここで、-d(または--date)はGNU拡張です。

したがって、単純なオプションはGNU dateを使用することです。GNU coreutilsパッケージをインストールする必要があるか、すでにインストールされている(Solarisでは/usr/sfw/binで確認)ことができます。おそらくgdateまたはgnudateとして利用できます。これは、YYYY-MM-DD形式で日付を適切に検証します(2015-31-01を受け入れる他の正規表現の例とは異なります)

代わりに、touchコマンドを同様の方法で使用できます 移植性が高い(POSIX) 方法

touch -c -d 2015-12-12T00:00:00 /tmp/does-not-exist
  • -cを使用して、ファイルが作成されないようにする
  • 日付にT00:00:00を追加して、有効なタイムスタンプを作成します

(ただし、Solarisを使用している場合、一部のバージョンに-dが不足しているだけでなく、少なくとも一部のバージョンにバグ/機能の誤りがあり、検証されないためにスマートにしようとするため、「2015-02-29」は「 2015-03-01」というエラーは発生しないため、これらのバージョンを日付検証に使用することはできません。)

私はこの方法を好みます。gawk(または代わりにmawkがありますが、従来のnawkにはこれらの時間関数がありません)を前提として、堅牢で移植性があります。

#!/usr/local/bin/gawk -f
BEGIN{
    split(ARGV[1],bb,/-/)
    tm=mktime( bb[1] " " bb[2] " " bb[3] " 00 00 00")
    tms=sprintf("%04i-%02i-%02i",bb[1],bb[2],bb[3])
    if (tms==strftime("%Y-%m-%d",tm)) exit 0
    exit 1
}

上記

  • 最初の引数を取り、「-」文字で分割します。
  • mktime()は、示されたYYYY-MM-DDのエポックタイムスタンプを決定します
  • sprintf()は、YYYY-MM-DD(先頭の0)を正規化します
  • strftime()エポック時間をYYYY-MM-DDに変換し、文字列として比較します

追加の変換と比較の理由は、Linuxのglibcの場合(Solaris touchと同じ問題)のように、疑わしい日付がCライブラリmktime()によって再解釈されるケースをキャッチするためです。上記)。

YYYY-MM-DDの正しい形式に注意することは、日付の有効性に注意することを意味する場合とそうでない場合があります(何かdateはdo)、そして YYYY-DD-MM形式の日付 を削除できることを意味する場合さえあります。形式が「日付のような」であることのみを確認したい場合は、正規表現で十分です。

grep -qE "^[0-9]{4}-[01]?[0-9]-[0123]?[0-9]$"
grep -qE "^[12][0-9]{3}-(0?[1-9]|10|11|12)-(0?[1-9]|[12][0-9]|3[01])$"

(Solarisでは、デフォルトのgrepではなく/usr/xpg4/bin/grepを使用してください)最初のものはほとんどの偽の日付を拒否し、2番目のものはほとんどすべての偽の日付を拒否します。 -qを使用すると、出力はなくなり、期待どおりに戻りコードを使用できます。 (^...$)を固定するか、正規表現を制限して、有効な部分文字列に単純に一致しないように注意してください。 2015-12-12345

0
mr.spuratic