回答:
「日付後のn週間」はGNU date(1)で簡単です:
$ date -d 'now + 3 weeks'
Tue Dec 6 23:58:04 EST 2011
$ date -d 'Aug 4 + 3 weeks'
Thu Aug 25 00:00:00 EST 2011
$ date -d 'Jan 1 1982 + 11 weeks'
Fri Mar 19 00:00:00 EST 1982
2つの日付の差を計算する簡単な方法は知りませんが、シェル関数を使用してdate(1)の周りに小さなロジックをラップできます。
datediff() {
d1=$(date -d "$1" +%s)
d2=$(date -d "$2" +%s)
echo $(( (d1 - d2) / 86400 )) days
}
$ datediff '1 Nov' '1 Aug'
91 days
スワップd1
しd2
、日付の計算を別の方法で行いたい場合、またはそれを問題にしないように少し手の込んだ方法を取得します。さらに、間隔に非DSTからDSTへの移行がある場合、日のうちの1 つはわずか 23時間です。合計に½日を追加することで補償できます。
echo $(( (((d1-d2) > 0 ? (d1-d2) : (d2-d1)) + 43200) / 86400 )) days
ポータブルツールのセットについては、独自のdateutilsを試してください。あなたの2つの例は、ワンライナーに要約されます:
ddiff 2011-11-15 2012-04-11
=>
148
または数週間と数日で:
ddiff 2011-11-15 2012-04-11 -f '%w %d'
=>
21 1
そして
dadd 2011-11-15 21w
=>
2012-04-10
dateadd -i '%m%d%Y' 01012015 +1d
動作しないように見えますが、無期限に停止します...日付の仕様が文字で区切られている場合は動作します...何か問題がありますか?)
私が惑星を歩いた日数を計算するためのpythonの例:
$ python
>>> from datetime import date as D
>>> print (D.today() - D(1980, 6, 14)).days
11476
ychaouche@ychaouche-PC ~ $ python -c "from datetime import date as d; print (d.today() - d(1980, 6, 14)).days"
12813
ychaouche@ychaouche-PC ~ $
私は通常、unix utime形式(70年代が始まったエポックからの秒数、UTC)で時刻/日付を持つことを好みます。そのように、それは常に秒の単純な減算または加算に要約されます。
通常、日付/時刻をこの形式に変換する問題になります。
シェル環境/スクリプトでは、これを取得できます。date '+%s'
執筆時点では、現在の時刻は1321358027
です。
2011-11-04(私の誕生日)と比較するにはdate '+%s' -d 2011-11-04
、を生成し1320361200
ます。減算:秒expr 1321358027 - 1320361200
を与えます。996827
これはexpr 996827 / 86400
= 11日前です。
utime(1320361200形式)から日付への変換は、標準ライブラリを使用して、たとえばC、PHP、またはperlで非常に簡単に実行できます。GNUを使用するdate
と、「エポックからの秒数」形式を示すために-d
引数を前に付けることができ@
ます。
date -d @1234567890
は、エポックからの秒数を指定した日付形式に変換します。
info date
、特にエポックからの秒ノードを:「あなたは`@」で番号の前にした場合、それは秒数として内部タイムスタンプを表している。」
グラフィカルツールで問題なければ、私は心からお勧めしますqalculate
(単位変換に重点を置いた計算機、GTKおよびKDEインターフェイス、IIRCが付属しています)。そこにあなたは言うことができます
days(1900-05-21, 1900-01-01)
日付間の日数(1900はle年ではないので140)を取得しますが、もちろん時間についても同じことができます:
17:12:45 − 08:45:12
利回り8.4591667
時間のか、あなたは、フォーマット時に出力を設定している場合、8:27:33
。
qalc
、その後、help days
。
qcalc
例:qalc -t 'days(1900-05-21, 1900-01-01)'
-> 140
これはdate -d "$death_date - $y years - $m months - $d days"
、出生日を取得するために使用するときに発生しました(系図用)。そのコマンドは間違っています。月はすべて同じ長さではありません(date + offset) - offset != date
。年齢は、年/月/日で、生年月日から先に進む指標です。
$ date --utc -d 'mar 28 1867 +72years +11months +2days'
Fri Mar 1 00:00:00 UTC 1940
$ date --utc -d 'mar 1 1940 -72years -11months -2days'
Sat Mar 30 00:00:00 UTC 1867
# (2 days later than our starting point)
日付はどちらの場合も正しい出力を提供しますが、2番目の場合は間違った質問をしていました。それは、日を追加/減算する前に、年の11か月間、+ /-11がカバーする重要なものです。例えば:
$ date --utc -d 'mar 31 1939 -1month'
Fri Mar 3 00:00:00 UTC 1939
$ date --utc -d 'mar 31 1940 -1month' # leap year
Sat Mar 2 00:00:00 UTC 1940
$ date --utc -d 'jan 31 1940 +1month' # leap year
Sat Mar 2 00:00:00 UTC 1940
減算を加算の逆演算にするには、演算の順序を逆にする必要があります。追加すると、年、次に月、次に日が追加されます。減算が逆の順序を使用した場合、開始点に戻ります。日付オフセットが異なる長さの月の月の境界を超える場合は、そうではありません。
終了日と年齢からさかのぼって作業する必要がある場合は、の複数の呼び出しで実行できますdate
。最初に日、次に月、次に年を減算します。(date
うるう年が2月の長さを変えるため、1回の呼び出しで年と月を組み合わせるのは安全ではないと思います。)
日付の計算にはSQLを頻繁に使用します。たとえば、MySQL、PostgreSQL、またはSQLite:
bash-4.2$ mysql <<< "select datediff(current_date,'1980-06-14')"
datediff(current_date,'1980-06-14')
11477
bash-4.2$ psql <<< "select current_date-'1980-06-14'"
?column?
----------
11477
(1 row)
bash-4.2$ sqlite2 <<< "select julianday('now')-julianday('1980-06-14');"
11477.3524537035
また、JavaScriptのムードを感じることもあります。たとえば、SpiderMonkey、WebKit、SeedまたはNode.js:
bash-4.2$ js -e 'print((new Date()-new Date(1980,5,14))/1000/60/60/24)'
11477.477526192131
bash-4.2$ jsc-1 -e 'print((new Date()-new Date(1980,5,14))/1000/60/60/24)'
11477.47757960648
bash-4.2$ seed -e '(new Date()-new Date(1980,5,14))/1000/60/60/24'
11477.4776318287
bash-4.2$ node -pe '(new Date()-new Date(1980,5,14))/1000/60/60/24'
11624.520061481482
(月をJavaScript Date
オブジェクトのコンストラクターに渡すときは注意してください。0で始まります。)
同じ暦年の2つの日付の差を計算する別の方法として、これを使用できます。
date_difference.sh
1 #!/bin/bash
2 DATEfirstnum=`date -d "2014/5/14" +"%j"`
3 DATElastnum=`date -d "12/31/14" +"%j"`
4 DAYSdif=$(($DATElastnum - $DATEfirstnum))
5 echo "$DAYSdif"
date
は、変数DATEfirstnumにoutからの値を割り当てます。-d
フラグは、この場合は5月14日2014年にタイム形式の文字列を表示し、+"%j"
伝えdate
年(1〜365)のちょうどその日に出力をフォーマットします。DAYSdif
は、2日間の差に値を割り当てます。DAYSdif
。これはGNUバージョンdate
ので動作しますが、PC-BSD / FreeBSDバージョンでは動作しません。coreutils
ポートツリーからインストールし、/usr/local/bin/gdate
代わりにコマンドを使用しました。
DATEfirstnum=$(date -d "$1" +%s)
DATElastnum=$(date -d "$2" +%s)
また、このスクリプトは2つの異なる年の間の差を計算できません。+%j
年の日(001..366)を参照するため、./date_difference.sh 12/31/2001 12/30/2014
-1を出力します。他の回答では、両方の日付を1970-01-01 00:00:00 UTC以降の秒に変換する必要があると指摘されています。
$
内部の算術式は必要ありません:$((DATElastnum - DATEfirstnum))
動作します。
dannasソリューションの助けを借りて、次のコードを使用してこれを1行で実行できます。
python -c "from datetime import date as d; print(d.today() - d(2016, 7, 26))"
(Python 2.xとPython 3の両方で動作します。)
また、GNU日付と組み合わされたGNUユニットの時間計算もあります。
$ gunits $(gdate +%s)sec-$(gdate +%s -d -1234day)sec 'yr;mo;d;hr;min;s'
3 yr + 4 mo + 16 d + 12 hr + 37 min + 26.751072 s
$ gunits $(gdate +%s -d '2015-1-2 3:45:00')sec-$(gdate +%s -d '2013-5-6 7:43:21')sec 'yr;mo;d;hr;min;s'
1 yr + 7 mo + 27 d + 13 hr + 49 min + 26.206759 s
(gunitsはLinuxの単位、gdateは日付)
#!/bin/bash
#Simplest calculator two dates difference. By default in days
# Usage:
# ./datediff.sh first_date second_date [-(s|m|h|d) | --(seconds|minutes|hours|days)]
first_date=$(date -d "$1" "+%s")
second_date=$(date -d "$2" "+%s")
case "$3" in
"--seconds" | "-s") period=1;;
"--minutes" | "-m") period=60;;
"--hours" | "-h") period=$((60*60));;
"--days" | "-d" | "") period=$((60*60*24));;
esac
datediff=$(( ($first_date - $second_date)/($period) ))
echo $datediff
camhの答えがその大部分を処理しますが、丸め、タイムゾーンなどに対処するように改善できます。さらに、精度を高め、ユニットを選択する機能を取得できます。
datediff() {
#convert dates to decimal seconds since 1970-01-01 00:00:00 UTC
date1seconds=$(date +%s.%N -d "$date1")
date2seconds=$(date +%s.%N -d "$date2")
#Calculate time difference in various time units
timeseconds=$(printf "%0.8f\n" $(bc <<<"scale=9; ($date2sec-$date1sec)"))
timeminutes=$(printf "%0.8f\n" $(bc <<<"scale=9; ($date2sec-$date1sec)/60"))
timehours=$(printf "%0.8f\n" $(bc <<<"scale=9; ($date2sec-$date1sec)/3600"))
timedays=$(printf "%0.8f\n" $(bc <<<"scale=9; ($date2sec-$date1sec)/86400"))
timeweeks=$(printf "%0.8f\n" $(bc <<<"scale=9; ($date2sec-$date1sec)/604800"))
}
-d
date
変換する日時を指定していることを伝えます。 +%s.%N
UTCの1970-01-01 00:00:00からdate.timeをseconds.nanosecondsに変更します。 bc
2つの数値の差を計算し、除算係数により異なる単位を取得します。 printf
必要に応じて小数点の前に0を追加し(必要でbc
はない)、丸めが最も近いことを確認します(bc
切り捨てます)。を使用することもできますawk
。
ファンキーなテストケースでこれを実行してみましょう。
date1='Tue Jul 9 10:18:04.031 PST 2020'
date2='Wed May 8 15:19:34.447 CDT 2019'
datediff "$date1" "$date2"
echo $timeseconds seconds
-36971909.584000000 seconds
echo $timeminutes minutes
-616198.493066667 minutes
echo $timehours hours
-10269.974884444 hours
echo $timedays days
-427.915620185 days
echo $timeweeks weeks
-61.130802884 weeks
月または年の長さが常に同じではないため、ここでは単一の「正しい」答えはありませんが、最近では365.24日を合理的な近似として使用できます。
awk Velorライブラリを使用できます。
velour -n 'print t_secday(t_utc("2017-4-12") - t_utc("2017-4-5"))'
または:
velour -n 'print t_secday(t_utc(ARGV[1]) - t_utc(ARGV[2]))' 2017-4-12 2017-4-5
結果:
7