192

Linuxで実行され、この呼び出しを使用して昨日の日付を次のYYYY-MM-DD形式で取得するシェルスクリプトがあります。

date -d "1 day ago" '+%Y-%m-%d'

ほとんどの場合は機能しますが、昨日の朝にスクリプトを実行すると、の代わりにスクリプトが2013-03-11 0:35 CDT返されました。"2013-03-09""2013-03-10"

おそらく、夏時間(昨日から始まった)が原因です。実装方法"1 day ago"は24時間差し引いたものだと思いますが、24時間前2013-03-11 0:35 CDTはでした2013-03-09 23:35 CST。これが結果になり"2013-03-09"ました。

では、Linuxで昨日の日付をbashで取得するための優れたDSTセーフな方法は何でしょうか。

4

10 に答える 10

316

実行する頻度や時期に関係なく、これは機能するはずだと思います...

date -d "yesterday 13:00" '+%Y-%m-%d'
于 2013-03-13T00:23:13.677 に答える
77

Mac OSXでの日付の動作はわずかに異なります。

昨日のために

date -v-1d +%F

先週の場合

date -v-1w +%F
于 2014-03-13T09:23:37.670 に答える
18

これも機能するはずですが、おそらく多すぎます。

date -d @$(( $(date +"%s") - 86400)) +"%Y-%m-%d"
于 2013-03-13T00:24:25.637 に答える
11

スクリプトが 1 日の最初の数時間に実行されることが確実な場合は、次のように簡単に実行できます。

  date -d "12 hours ago" '+%Y-%m-%d'

ところで、スクリプトが毎日 00:35 に (crontab 経由で) 実行される場合、その時間に DST の変更があった場合に何が起こるかを自問する必要があります。スクリプトを実行できなかったか、場合によっては 2 回実行されました。ただし、の最新の実装はcron、この点で非常に巧妙です。

于 2013-03-13T00:30:25.243 に答える
5

これは、Solaris と AIX でも機能するソリューションです。

タイムゾーンを操作して、時計を数時間変更することができます。夏時間のため、24 時間前は今日または一昨日になることがあります。

昨日が 20 時間または 30 時間前であることは確かです。どれ?さて、今日ではない最新のもの。

echo -e "$(TZ=GMT+30 date +%Y-%m-%d)\n$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1

echo コマンドで使用される -e パラメーターは、bash では必要ですが、ksh では機能しません。ksh では、-e フラグなしで同じコマンドを使用できます。

スクリプトをさまざまな環境で使用する場合は、スクリプトを #!/bin/ksh または #!/bin/bash で開始できます。\n を改行に置き換えることもできます。

echo "$(TZ=GMT+30 date +%Y-%m-%d)
$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1
于 2014-01-22T12:55:43.933 に答える
1

date信頼できる秒を使用するだけです:

ご指摘のとおり、英語の時間演算に依存している場合、基礎となる計算に関する詳細の多くが隠されています。たとえば-d yesterday、 と-d 1 day agoは異なる動作をします。

代わりに、UNIXエポックUTCからの(正確に文書化された)秒に確実に依存し、算術演算を実行して必要な瞬間を取得できます。

date -d @$(( $(date +"%s") - 24*3600)) +"%Y-%m-%d"

これは別の回答で指摘されました。この形式は、さまざまなコマンド ライン フラグを使用するプラットフォーム間で移植性が高くdate、言語に依存せず (たとえば、フランス語のロケールでは「yesterday」と「hier」)、率直に言って (長期的には) 覚えやすくなります。すでに知っています。そうでなければ、あなたは自問し続けるかもしれませ-d 2 hours ago-d 2 hour ago: または「それは私が欲しいですか?」)-d yesterday-d 1 day agoここでの唯一の注意点は、@.

bashだけで武装:

bash のみで bash を実行すると、printf ビルトインを使用して昨日の時刻を取得することもできます。

 %(datefmt)T
     causes printf to output the date-time string resulting from using
     datefmt as a format string for strftime(3).  The  corresponding  argu‐
     ment  is an integer representing the number of seconds since the
     epoch.  Two special argument values may be used: -1 represents the
     current time, and -2 represents the time the shell was invoked.
     If no argument is specified, conversion behaves as if -1 had
     been  given.
     This is an exception to the usual printf behavior.

そう、

# inner printf gets you the current unix time in seconds
# outer printf spits it out according to the format
printf "%(%Y-%m-%d)T\n" $(( $(printf "%(%s)T" -1) - 24*3600 ))

または、同等に一時変数を使用します(外側のサブシェルはオプションですが、環境変数をクリーンに保ちます)。

(
  now=$(printf "%(%s)T" -1);
  printf "%(%Y-%m-%d)T\n" $((now - 24*3600));
)

注:%()Tフォーマッタへの引数はデフォルトを想定しないとマンページに記載されています-1が、代わりに 0 を取得しているようです(ありがとう、bashマニュアルバージョン4.3.48)

于 2018-03-29T08:26:41.323 に答える