2 つの日付間の視差の計算

2 つの日付間の視差の計算

スクリプトの開始と停止のタイミングを知るために、クローンジョブの実行時間を追跡する愚かなスクリプトがあります。

start=$(date +'%Y-%m-%d %H:%M:%S') # This line converts to 2019-09-10 00:50:48
echo "$start"

./actual_script_runs_here

stop=$(date +'%Y-%m-%d %H:%M:%S')
echo "$stop"

この方法は効果的です。しかし、スクリプトを実行するのにかかる時間は、自分で計算する必要があります。 bashで計算できますか?

または、コマンドを使用することもできますtime。ただし、3つの異なる結果を返し、3つの新しい行が含まれます。私のスクリプト結果とともに、時間の結果が1行に表示されるのを見たいと思います。

答え1

これを使用して、date +%s数学的に簡単に計算できる日付形式(1970年1月1日00:00:00Z以降の秒数[注意事項])を取得できます。を使用することもできますdate -d "$start" +%s。再変換時に夏時間の問題があるだけでなく、プログラムの実行中に誰かが時間を変更したり、ntpなどの場合に間違った答えが得られるため、理想的ではありません。おそらく非常に間違っているようです。

うるう秒は少し間違った答えを提供します(1秒)。

残念ながら確認してみるとタイムソースコードtime、(「単調な」時間ではなく)壁時計を使用するのと同じ問題を抱えているようです。ありがたいことに、Perlはほとんどどこでも利用でき、単調なタイマーへのアクセスを提供します。

start=$(perl -MTime::HiRes=clock_gettime,CLOCK_MONOTONIC -E 'say clock_gettime(CLOCK_MONOTONIC)')

過去の特定の時点(Linuxでは起動後、システムが停止した時間は含まれません)以降の秒数を取得します。時計が変わっても秒を計算します。実数(整数ではない)を処理するのはシェルではやや難しいので、Perlですべてのことを行うことができます。

#!/usr/bin/perl
use warnings qw(all);
use strict;

use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);

my $cmd   = $ARGV[0];
my $start = clock_gettime(CLOCK_MONOTONIC);

system $cmd @ARGV; # this syntax avoids passing it to "sh -c"

my $exit_code = $?;
my $end       = clock_gettime(CLOCK_MONOTONIC);
printf STDERR "%f\n", $end - $start;

exit($exit_code ? 127 : 0);

私はそれを「鍛造時間」と命名しました。これは「時間」と同様に使用されます(自己引数なし)。だから:

$ monotonic-time sleep 5
5.001831                 # appeared ≈5s later
$ monotonic-time fortune -s
Good news is just life's way of keeping you off balance.
0.017800

答え2

Bashではマジック変数を使用することもできますSECONDS

SECONDS
このパラメータが参照されるたびにシェルが呼び出されてからの秒数が返されます。

だから:

bash -c 'a=$SECONDS; sleep 5; b=$SECONDS; printf "%d seconds passed\n" "$((b-a))"'

出力5 seconds passed

SECONDS完全な粒度のみですが、date +"... %S"GNU日付の場合は%Nwithを使用して%s時間をナノ秒単位で取得できます。

a=$(date +%s%N)
sleep 1.234
b=$(date +%s%N)
diff=$((b-a))
printf "%s.%s seconds passed\n" "${diff:0: -9}" "${diff: -9:3}"

印刷:

1.237 seconds passed

Bashは浮動小数点数で演算を実行できないため、外部ユーティリティを使用して計算を実行するか、上記のように1秒未満の単位で実行する必要があります。 (この数字は32ビットに収まらないため、32ビットシステムでは機能しない可能性があります。32ビットシステムでも、Bashが算術に64ビットを使用しているかどうかはわかりません。)

SECONDS測定中にシステム時間が修正されてもエラーが発生する可能性がありますが、実際には起動時に時間を一度だけ設定し、NTPが時間を維持するように時計を調整する必要があります。

答え3

誰もPythonの使用について何も言わなかったという事実に驚きました!たとえば、5日前はyyyymmddです。

MYDATE=$( python -c 'from datetime import date, timedelta; 
    print( ( date.today() - timedelta(days=5) ).strftime("%Y%m%d"))' )

仕事より小さい単位で作業するにはインポートし、可能であればそれを使用してdatetimeください。datetime.now()

関連情報