web-dev-qa-db-ja.com

2つの日付の日数の違いを見つける方法は?

A = "2002-20-10"
B = "2003-22-11"

2つの日付の日数の違いを見つける方法は?

66
Tree

GNU dateがある場合、任意の日付の表現を印刷できます(-dオプション)。この場合、日付をエポックからの秒数に変換し、24 * 3600で減算して除算します。

または、ポータブルな方法が必要ですか?

26
user332325

Bashの方法-日付を%y%m%d形式に変換すると、コマンドラインから直接これを実行できます。

echo $(( ($(date --date="031122" +%s) - $(date --date="021020" +%s) )/(60*60*24) ))
57
techjacker

そしてPythonで

$python -c "from datetime import date; print (date(2003,11,22)-date(2002,10,20)).days"
398
16
Fred Laurent

気を付けて!ここでの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) ))

うるう秒は差に加算されるだけなので、常に前の日付を後の日付から減算する限り、これはうるう秒でも安全です。切り捨ては事実上正しい結果に切り捨てられます。

16
evan_b

便宜上、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!

7
nickl-

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
4
glenn jackman

システムでオプション-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`
4
Ruchi

これは私のために働く:

A="2002-10-20"
B="2003-11-22"
echo $(( ($(date -d $B +%s) - $(date -d $A +%s)) / 86400 )) days

プリント

398 days

何が起きているのですか?

  1. AおよびBに有効な時間文字列を指定します
  2. date -dを使用して、時間文字列を処理します
  3. date %sを使用して、1970年以降の時間文字列を秒に変換します(unix epoche)
  4. bashパラメーター展開 を使用して秒を減算します
  5. 1日あたりの秒数(86400 = 60 * 60 * 24)で除算して、日としての差を取得します
  6. DST は考慮されません! nix.stackexchange !でこの回答を参照してください。
3
jschnasse

Rubyで別の可能な解決策を提出します。今までで一番小さくてきれいに見えます:

A=2003-12-11
B=2002-10-10
DIFF=$(Ruby -rdate -e "puts Date.parse('$A') - Date.parse('$B')")
echo $DIFF
1
GreyCat

これは私が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
1
Gotxi

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 
1
mattymik

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 のドキュメントを参照してください

1

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

0
osexp2003

別のPythonバージョン:

python -c "from datetime import date; print date(2003, 11, 22).toordinal() - date(2002, 10, 20).toordinal()"
0
Ulf

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

0
bruce

これは、月が年の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])
}
0
Steven Penny

これを試してみてください:

Perl -e 'use Date::Calc qw(Delta_Days); printf "%d\n", Delta_Days(2002,10,20,2003,11,22);'
0

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日」)を変更します。

0
Alex Cherkas