A = "2002-20-10"
B = "2003-22-11"
2つの日付の日数の違いを見つける方法は?
A = "2002-20-10"
B = "2003-22-11"
2つの日付の日数の違いを見つける方法は?
回答:
GNUdate
を使用している場合は、任意の日付の表現を印刷できます(-d
オプション)。この場合、日付をEPOCHからの秒数に変換し、24 * 3600で減算して除算します。
または、ポータブルな方法が必要ですか?
echo "( `date -d $B +%s` - `date -d $A +%s`) / (24*3600)" | bc -l
bashの方法-日付を%y%m%d形式に変換すると、コマンドラインから直接実行できます。
echo $(( ($(date --date="031122" +%s) - $(date --date="021020" +%s) )/(60*60*24) ))
%y%m%d
フォーマットされている必要はありません。たとえば、gnu dateは%Y-%m-%d
、OPが使用した形式を受け入れます。一般に、ISO-8601が適切な選択です(OPの形式はそのような形式の1つです)。2桁の年の形式は避けた方がよいでしょう。
days_diff=$(( (`date -d $B +%s` - `date -d "00:00" +%s`) / (24*3600) ))
。$days_diff
整数になることに注意してください(つまり、小数はありません)
date
インストールされているバリアントによって異なります。GNUで動作しますdate
。POSIXでは動作しませんdate
。これはおそらくほとんどの読者にとって問題ではありませんが、注目に値します。
%Y-%m-%d
August 2.0
October 2.0
%Y-%d-%m
tl; dr
date_diff=$(( ($(date -d "2015-03-11 UTC" +%s) - $(date -d "2015-03-05 UTC" +%s)) / (60*60*24) ))
気を付けて!ここでのbashソリューションの多くは、夏時間が始まる日付にまたがる日付範囲で壊れています(該当する場合)。これは、$((math))構文が結果の値に対して「floor」/切り捨て操作を実行し、整数のみを返すためです。説明させてください:
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) ))
また、うるう秒は差に追加されるだけなので、常にうるう秒から早い日付を引く限り、うるう秒は安全です。切り捨ては事実上正しい結果に切り捨てられます。
echo $(( ($(date --date="2015-03-11 UTC" +%s) - $(date --date="2015-03-05 UTC" +%s) )/(60*60*24) ))
、6を返すのではなく、5
そしてPythonで
$python -c "from datetime import date; print (date(2003,11,22)-date(2002,10,20)).days"
398
bash
ととして指定しているshell
ので、* nixシステムについて話していると推測できます。そのようなシステム内で、echo
そしてdate
確実に存在しますが、pythonは存在しません。
これは私のために働きます:
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)オプション-dがシステムで機能する場合は、別の方法があります。年間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`
これがあなたの便宜のためのMACOSXバージョンです。
$ 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!
A="2002-20-10"; B="2003-22-11"
echo $(((`date -jf "%Y-%d-%m" "$B" +%s` - `date -jf "%Y-%d-%m" "$A" +%s`)/86400))
。つまり、形式と変数の両方を二重引用符で囲みます。そうしないと、異なる日付形式(例%b %d, %Y
/ Jul 5, 2017
)で失敗する可能性があります
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
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
これがzshを使用した私の作業アプローチです。OSXでテスト済み:
# Calculation dates
## A random old date
START_DATE="2015-11-15"
## Today's date
TODAY=$(date +%Y-%m-%d)
# Import zsh date mod
zmodload zsh/datetime
# Calculate number of days
DIFF=$(( ( $(strftime -r %Y-%m-%d $TODAY) - $(strftime -r %Y-%m-%d $START_DATE) ) / 86400 ))
echo "Your value: " $DIFF
結果:
Your value: 1577
基本的に、strftime
reverse(-r
)機能を使用して日付文字列をタイムスタンプに変換し直してから、計算を行います。
Rubyで別の可能な解決策を提出します。これまでで最も小さく、最もきれいに見えるもののように見えます:
A=2003-12-11
B=2002-10-10
DIFF=$(ruby -rdate -e "puts Date.parse('$A') - Date.parse('$B')")
echo $DIFF
date
またはいくつかのスクリプト言語)を使用しており、Rubyがここに行くのに良い方法だと正直に思います。このソリューションは非常に短く、非標準のライブラリやその他の依存関係を使用しません。実際、GNUの日付をインストールするよりもRubyをインストールする可能性が高いと思います。
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のドキュメントを参照してください
これを試してみてください:
perl -e 'use Date::Calc qw(Delta_Days); printf "%d\n", Delta_Days(2002,10,20,2003,11,22);'
OracleDBバックアップを3次ディスクに手動でrsyncするとします。次に、そのディスク上の古いバックアップを削除します。だからここに小さな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
ニーズに合わせて、dirと保持期間(「30日」)を変更します。
MacOS sierra(おそらくMac OS X yosemateから)の場合、
ファイルからエポックタイム(1970年からの秒数)を取得し、それをvarに保存するには:
old_dt=`date -j -r YOUR_FILE "+%s"`
現在の時間のエポック時間を取得するには
new_dt=`date -j "+%s"`
上記の2つのエポック時間の差を計算するには
(( diff = new_dt - old_dt ))
差分が23日以上かどうかを確認するには
(( new_dt - old_dt > (23*86400) )) && echo Is more than 23 days
echo $(date +%d/%h/%y) date_today
echo " The other date is 1970/01/01"
TODAY_DATE="1970-01-01"
BEFORE_DATE=$(date +%d%h%y)
echo "THE DIFFERNS IS " $(( ($(date -d $BEFORE_DATE +%s) - $(date -d $TODAY_DATE +%s)) )) SECOUND
それを使用して、今日の日付と希望の日付からの秒を取得します。日数でそれが必要な場合は、86400で割ってください
echo $(date +%d/%h/%y) date_today
echo " The other date is 1970/01/01"
TODAY_DATE="1970-01-01"
BEFORE_DATE=$(date +%d%h%y)
echo "THE DIFFERNS IS " $(( ($(date -d $BEFORE_DATE +%s) - $(date -d $TODAY_DATE +%s))/ 86400)) SECOUND