A = "2002-20-10"
B = "2003-22-11"
2つの日付の日数の違いを見つける方法は?
GNU date
がある場合、任意の日付の表現を印刷できます(-d
オプション)。この場合、日付をエポックからの秒数に変換し、24 * 3600で減算して除算します。
または、ポータブルな方法が必要ですか?
Bashの方法-日付を%y%m%d形式に変換すると、コマンドラインから直接これを実行できます。
echo $(( ($(date --date="031122" +%s) - $(date --date="021020" +%s) )/(60*60*24) ))
そしてPythonで
$python -c "from datetime import date; print (date(2003,11,22)-date(2002,10,20)).days"
398
気を付けて!ここでのbashソリューションの多くは、夏時間の開始日(該当する場合)にまたがる日付範囲では壊れています。これは、$((math))コンストラクトが結果の値に対して 'floor'/truncation操作を実行し、整数のみを返すためです。私に説明させてください:
DSTは今年3月8日に米国で開始されたため、次の期間を使用してみましょう。
start_ts=$(date -d "2015-03-05" '+%s')
end_ts=$(date -d "2015-03-11" '+%s')
二重括弧で得られるものを見てみましょう:
echo $(( ( end_ts - start_ts )/(60*60*24) ))
「5」を返します。
'bc'を使用してこれをより正確に行うと、異なる結果が得られます。
echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc
「5.95」を返します-欠落している0.05は、DSTスイッチオーバーからの失われた時間です。
それでは、これをどのように正しく行う必要がありますか?
代わりにこれを使用することをお勧めします。
printf "%.0f" $(echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc)
ここで、「printf」は「bc」で計算されたより正確な結果を丸め、「6」の正しい日付範囲を提供します。
編集:最近使用している@ hank-schultzのコメントで回答を強調表示します。
date_diff=$(( ($(date -d "2015-03-11 UTC" +%s) - $(date -d "2015-03-05 UTC" +%s) )/(60*60*24) ))
うるう秒は差に加算されるだけなので、常に前の日付を後の日付から減算する限り、これはうるう秒でも安全です。切り捨ては事実上正しい結果に切り捨てられます。
便宜上、MAC OS Xバージョンを紹介します。
$ A="2002-20-10"; B="2003-22-11";
$ echo $(((`date -jf %Y-%d-%m $B +%s` - `date -jf %Y-%d-%m $A +%s`)/86400))
nJoy!
GNUの日付がなくても、おそらくPerlがインストールされているでしょう:
use Time::Local;
sub to_Epoch {
my ($t) = @_;
my ($y, $d, $m) = ($t =~ /(\d{4})-(\d{2})-(\d{2})/);
return timelocal(0, 0, 0, $d+0, $m-1, $y-1900);
}
sub diff_days {
my ($t1, $t2) = @_;
return (abs(to_Epoch($t2) - to_Epoch($t1))) / 86400;
}
print diff_days("2002-20-10", "2003-22-11"), "\n";
これは、398.041666666667
-398日と夏時間のための1時間を返します。
質問が私のフィードに戻ってきました。 Perlバンドルモジュールを使用したより簡潔な方法を次に示します。
days=$(Perl -MDateTime -le '
sub parse_date {
@f = split /-/, shift;
return DateTime->new(year=>$f[0], month=>$f[2], day=>$f[1]);
}
print parse_date(shift)->delta_days(parse_date(shift))->in_units("days");
' $A $B)
echo $days # => 398
システムでオプション-dが機能する場合、別の方法があります。私は1年365日を検討してきたので、うるう年を考慮しないという警告があります。
date1yrs=`date -d "20100209" +%Y`
date1days=`date -d "20100209" +%j`
date2yrs=`date +%Y`
date2days=`date +%j`
diffyr=`expr $date2yrs - $date1yrs`
diffyr2days=`expr $diffyr \* 365`
diffdays=`expr $date2days - $date1days`
echo `expr $diffyr2days + $diffdays`
これは私のために働く:
A="2002-10-20"
B="2003-11-22"
echo $(( ($(date -d $B +%s) - $(date -d $A +%s)) / 86400 )) days
プリント
398 days
何が起きているのですか?
date -d
を使用して、時間文字列を処理しますdate %s
を使用して、1970年以降の時間文字列を秒に変換します(unix epoche)Rubyで別の可能な解決策を提出します。今までで一番小さくてきれいに見えます:
A=2003-12-11
B=2002-10-10
DIFF=$(Ruby -rdate -e "puts Date.parse('$A') - Date.parse('$B')")
echo $DIFF
これは私がcentos 7で作業することができた最も簡単なものです:
OLDDATE="2018-12-31"
TODAY=$(date -d $(date +%Y-%m-%d) '+%s')
LINUXDATE=$(date -d "$OLDDATE" '+%s')
DIFFDAYS=$(( ($TODAY - $LINUXDATE) / (60*60*24) ))
echo $DIFFDAYS
uNIXでは、GNUの日付をインストールする必要があります。 bashから逸脱する必要はありません。ここでは、手順を示すために、数日を考慮した取り残されたソリューションを示します。簡略化して完全な日付に拡張できます。
DATE=$(echo `date`)
DATENOW=$(echo `date -d "$DATE" +%j`)
DATECOMING=$(echo `date -d "20131220" +%j`)
THEDAY=$(echo `expr $DATECOMING - $DATENOW`)
echo $THEDAY
http://cfajohnson.com/Shell/ssr/ssr-scripts.tar.gz ;からシェル関数を使用します。標準のUnixシェルで動作します。
date1=2012-09-22
date2=2013-01-31
. date-funcs-sh
_date2julian "$date1"
jd1=$_DATE2JULIAN
_date2julian "$date2"
echo $(( _DATE2JULIAN - jd1 ))
http://cfajohnson.com/Shell/ssr/08-The-Dating-Game.shtml のドキュメントを参照してください
MacOSシエラ(Mac OS X yosemateからの場合があります)の場合、
ファイルからエポック時間(1970年からの秒数)を取得し、変数に保存するには:old_dt=`date -j -r YOUR_FILE "+%s"`
現在の時間のエポック時間を取得するにはnew_dt=`date -j "+%s"`
上記の2つのエポック時間の差を計算するには(( diff = new_dt - old_dt ))
Diffが23日以上かどうかを確認するには(( new_dt - old_dt > (23*86400) )) && echo Is more than 23 days
別のPythonバージョン:
python -c "from datetime import date; print date(2003, 11, 22).toordinal() - date(2002, 10, 20).toordinal()"
Mysqlコマンドを使用する
$ echo "select datediff('2013-06-20 18:12:54+08:00', '2013-05-30 18:12:54+08:00');" | mysql -N
結果:21
注:値の日付部分のみが計算に使用されます
リファレンス: http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_datediff
これは、月が年の1/12であると仮定しています。
#!/usr/bin/awk -f
function mktm(datespec) {
split(datespec, q, "-")
return q[1] * 365.25 + q[3] * 365.25 / 12 + q[2]
}
BEGIN {
printf "%d\n", mktm(ARGV[2]) - mktm(ARGV[1])
}
これを試してみてください:
Perl -e 'use Date::Calc qw(Delta_Days); printf "%d\n", Delta_Days(2002,10,20,2003,11,22);'
Oracle DBバックアップを手動でターシャリディスクに再同期するとします。次に、そのディスク上の古いバックアップを削除します。これが小さなbashスクリプトです:
#!/bin/sh
for backup_dir in {'/backup/cmsprd/local/backupset','/backup/cmsprd/local/autobackup','/backup/cfprd/backupset','/backup/cfprd/autobackup'}
do
for f in `find $backup_dir -type d -regex '.*_.*_.*' -printf "%f\n"`
do
f2=`echo $f | sed -e 's/_//g'`
days=$(((`date "+%s"` - `date -d "${f2}" "+%s"`)/86400))
if [ $days -gt 30 ]; then
rm -rf $backup_dir/$f
fi
done
done
必要に応じて、ディレクトリと保持期間(「30日」)を変更します。