日付:現在の15分間隔を取得します。

日付:現在の15分間隔を取得します。

dateコマンドまたは同様のコマンドを使用して現在の15分間隔を取得する方法はありますか?

たとえば、日付などの項目は、%Y.%m.%d %H:%M からまでの時間範囲で2011.02.22 10:19生成する必要がある項目を提供します。2011.02.22 10:1510:1510:29

答え1

現在のUnixタイムスタンプを取得し、単純なdate "+%s"数学で現在の分岐時間を見つけて(例はにありますbash)、より良い形式で再印刷できますdate

curdate=`date "+%s"`
curquarter=$(($curdate - ($curdate % (15 * 60))))
date -d"@$curquarter"

タイムスタンプで現在の日付と時刻を設定する構文は、@現在までのGNU拡張です。 OSで動作していない場合は、これと同じことができます(UTCを指定することを忘れないでください。そうしないと動作しません)。働かない):

date -d"1970-01-01 $curquarter seconds UTC"

答え2

次のメソッドを使用すると、これをdate2回呼び出す必要はありません。
システムコールのオーバーヘッドにより、「シンプル」コマンドは、独自のローカル環境で同じ操作を実行するbashよりも100倍遅くなる可能性があります。

修正する上記で私の意見に言及すると、「100倍遅い」です。これで、「を読むことができます。500何度も遅い"...最近この問題をブロックしました(いいえ、盲目的に)。リンクは次のとおりです。テストファイルを作成する簡単な方法

eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00  
echo $Y.$m.$d $H:$M  

または

eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
if   [[ "$M" < "15" ]] ; then M=00
elif [[ "$M" < "30" ]] ; then M=15
elif [[ "$M" < "45" ]] ; then M=30
else M=45
fi
echo $Y.$m.$d $H:$M

どちらのバージョンも返されます。

2011.02.23 01:00
2011.02.23 01:15
2011.02.23 01:30
2011.02.23 01:45   

これは60個の値すべてをテストする最初のループです。 ​{00..59}

for X in {00..59} ;                         ###### TEST
do                                          ###### TEST 
  eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
  M=$X                                      ###### TEST 
  [[ "$M" < "15" ]] && M=00 # cater for octal clash
  M=$(((M/15)*15))
  ((M==0)) && M=00 # the math returns 0, so make it 00  
  echo $Y.$m.$d $H:$M 
done                                        ###### TEST 

答え3

これがシェルで日付を処理する方法です。最初に呼び出しdateてコンポーネントを取得し、位置引数(など)をコンポーネントで埋めます$1$2これは$(…)、文字列を単語に分割するために二重引用符の外側を実際に使用したい場合があります)。次に、算術、テスト、またはコンポーネントに対して実行する必要があるすべての操作を実行します。最後にコンポーネントを組み立てます。

0算術部分は、シェルがそれを8進数の接頭辞として扱うため、少しトリッキーである可能性があります。たとえば、これは$(($5/15))8時間または9分後に失敗します。リーダー0は最大1つなので演算${5#0}に安全です。 100を加えて減算することは、1出力から固定数のビットを取得する1つの方法です。

set $(date "+%Y %m %d %H %M")
m=$((100+15*(${5#0}/15)))
last_quarter_hour="$1.$2.$3 $4:${m#1}"

答え4

一部のシェルは外部コマンドを呼び出さずにこれを実行しますdate

a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "#$((a-a%(15*60)))"
a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "$((a-a%(15*60)))"
zmodload zsh/datetime; a=$EPOCHSECONDS; strftime '%Y-%m-%d %H:%M' $((a-a%(15*60)))

上記の3つはローカル(UTCではない)時間を提供します。必要に応じて、前にTZ = UTC0を使用してください。

kshとbashの構文はほぼ同じです(#kshで必要な場合を除く)。 zshを使用するには、モジュール(zshディストリビューションに含まれている)をロードする必要があります。

これは(GNU)awkを使用して行うこともできます。

awk 'BEGIN{t=systime();print strftime("%Y.%m.%d %H:%M",t-t%(15*60),1)}'

ローカルが必要な場合は、UTC結果が提供されます(最後の結果1をに変更)。0ただし、外部awkまたは外部zshモジュールのロードは、日付自体を呼び出すのと同じくらい遅くなります。

a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'

小さな実行可能ファイルもbusybox同様の結果を提供できます。

a=$(busybox date +%s);busybox date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'

busyboxがPATHディレクトリの対応する名前に関連付けられている場合は、前のbusyboxの単語を省略できます。

date上記の両方がbusybox dateUTC時間を印刷します。-u現地時間オプションが削除されました。


オペレーティングシステムにさらに制限された日付バージョン(使用する必要がある)がある場合は、以下を試してください。

a=$(date +%s); a=$(( a-a%(15*60) ))
date -d"1970-01-01 $a seconds UTC" +'%Y.%m.%d %H:%M'

またはFreeBSDの場合は、以下を試してください。

a=$(date +%s); a=$(( a-a%(15*60) ))
date -r "$a" +'%Y.%m.%d %H:%M'

関連情報