date コマンド

現在の時刻を取得したり、設定したりするコマンド。OSが刻んでいる日時がずれている場合は、root権限でこのコマンドを使って正しい日時を設定する。

時刻の表示フォーマットを指定することもできる。

「30日後は何日か?」などの簡単な日時の計算もできる。

現在日時ではなく、処理にかかる時間を測定するにはtimeコマンドを使う。

基本的な使い方

# 現在の日時を表示
$ date

# 現在の日時をUTCで表示
$ date -u

# フォーマットは + で始まる書式で指定
$ date "+%Y%m%d-%H%M%S"

# 24時間後の日時を表示
$ date -d tomorrow

# -d の代わりに --date でも同じ
$ date --date tomorrow

# 30日後の日付を表示
date "+%Y/%m/%d" -d "30 days"

OSが刻んでいる現在日時を修正するにはroot権限で実行する。

$ sudo date -s "2013/09/04 12:17:00"

オプション

-d 日時, --date 日時
日時を指定
-u, --utc, --universal
UTCで表示
-r ファイルパス, --reference=ファイルパス
ファイルの更新日時を表示
--help
ヘルプ表示
--version
バージョン表示

日時表示のフォーマットのサンプル

よくあるフォーマットのチートシート。

フォーマット コマンド例 出力サンプル
YYYY/MM/DD hh:mm:ss date "+%Y/%m/%d %H:%M:%S" 2017/09/07 07:16:51
YYYY-MM-DDThh:mm:ss date +%Y-%m-%dT%H:%M:%S 2017-09-07T07:16:51
YYYYMMDD-hhmmss date +%Y%m%d-%H%M%S 20170907-071651

日時表示のフォーマットの一覧

+ で始まる書式指定には以下が使える。

%-d などの - は 桁数が足りないときに 0 で詰めることはしない、という意味。
%_d のように - の代わりに _ にすると、スペースで詰めてくれる。

%Y 西暦の4桁の年
%y 西暦の下2桁の年 00 〜 99
%-y 西暦の下2桁の年 0 〜 99

%m 01 〜 12
%-m 1 〜 12
%b Jan 〜 Dec
%h Jan 〜 Dec。%b と同じ。
%B January 〜 December

%U その年のなかで何番目の週か。日曜を週のはじめとみなして数える。00 〜 53

曜日

%a Sun, Mon, Tue, Wed, Thu, Fri, Sat
%A Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
%u 1 〜 7。1が月曜日、7が日曜日
%w 0 〜 6。0が日曜日、6が土曜日

%d 01 〜 31
%-d 1 〜 31
%e 1 〜 31。%_d と同じで、1桁の場合はスペースで埋める
%j 001 〜 366。1月1日が001、うるう年の12月31日が366
%-j 1 〜 366。1月1日が1、うるう年の12月31日が366

%H 00 〜 23
%-H 0 〜 23
%k 0 〜23。 %_H と同じで、1桁の場合はスペースで埋める
%I 01 〜 12
%-I 1 〜 12
%l 1 〜12。 %_I と同じで、1桁の場合はスペースで埋める

%M 00 〜 59
%-M 0 〜 59

%S 00 〜 59
%-S 0 〜 59
%s UNIX時刻 (1970年1月1日0時UTCからのうるう秒を考慮しない秒数)
%N ナノ秒。000000000 〜 999999999

その他

%D %m/%d/%y と同じ。例 03/20/16
%F %Y-%m-%d と同じ。例 2016-03-20
%R %H:%M と同じ。例 21:49
%T %H:%M:%S と同じ。例 21:49:10
%% % という文字
%n 改行
%t タブ

日時の指定方法

-d または --date オプションではさまざまなフォーマットで日時を指定することができ、簡単な日付の計算もできる。

# 1日後
$ date -d '1 day'

# 2日後
$ date -d '2 days

ago を付ければ過去の日時になる。

# 1日前
$ date -d '1 day ago'

数字を負にすれば逆向きになる。

# 1日前
$ date -d '-1 day'

# 1日後
$ date -d '-1 day ago'

次のような表現もできる。

# 1日前
$ date -d yesterday

# 1日後
$ date -d tomorrow

# 7日後
$ date -d week

# 14日後
$ date -d fortnight

単数形複数形を間違えても大丈夫。

$ date -d '1 days ago'
$ date -d '2 day ago'

1は省略しても大丈夫。

# 1日前
$ date -d 'day ago'

日以外の単位もある。

# 1ヶ月前
$ date -d '1 month ago'

# 1年前
$ date -d '1 year ago'

# 1時間前
$ date -d '1 hour ago'

# 1分前
$ date -d '1 minute ago'

# 1秒前
$ date -d '1 second ago'

現在日時ではなく、特定の日付を指定することもできる。

$ date -d '2015/04/25'

これらを組み合わせることもできる。

# 1年と10日前
$ date -d '1 year ago 10 days ago'

# 1時間半後
$ date -d '1 hour ago 30 minutes'

# 1日と12時間後
$ date -d '1 day ago 12 hours'

# 48時間後
$ date -d '48 hours'

# 特定の日付からの相対指定
$ date -d '2015/04/25 1 month'
Mon May 25 00:00:00 JST 2015

月単位の計算は月によって日数が異なるので注意が必要。

# 1月31日の1か月後は、2月31日つまり3月3日
$ date -d '2015/01/31 1 month'
Tue Mar  3 00:00:00 JST 2015

# 3月31日の1か月前も3月3日
$ date -d '2015/03/31 1 month ago'
Tue Mar  3 00:00:00 JST 2015

当月の1日を表示させたい場合。

# 当月の1日
$ date '+%Y/%m/01'
# または
$ date -d `date '+%Y/%m/01'`

月末の日付をちゃんと計算するのはちょっと面倒。

# 当月の末日
$ date -d "`date '+%Y/%m/01' -d "\`date '+%Y/%m/01'\` 1 month"` 1 day ago"

# 特定の日付(2015/03/15)の月の末日
$ date -d "`date '+%Y/%m/01' -d "\`date '+%Y/%m/01' -d 2015/03/15\` 1 month"` 1 day ago"

末日を得る上のコマンドの導出は以下のとおり。つまりいったん翌月の1日を計算し、その前日を当月の末日としている。

# 特定の日付の月の1日をフォーマットを指定して表示
$ date '+%Y/%m/01' -d 2015/03/15

# 特定の日付の翌月の1日
$ date -d "`date '+%Y/%m/01' -d 2015/03/15` 1 month"

# 特定の日付の翌月の1日をフォーマットを指定して表示
$ date '+%Y/%m/01' -d "`date '+%Y/%m/01' -d 2015/03/15` 1 month"

# 特定の日付の翌月の1日の前日 (つまり特定の日付の月末日)
$ date -d "`date '+%Y/%m/01' -d "\`date '+%Y/%m/01' -d 2015/03/15\` 1 month"` 1 day ago"

# 当月の末日
$ date -d "`date '+%Y/%m/01' -d "\`date '+%Y/%m/01'\` 1 month"` 1 day ago"

HOWTO

YYYY/MM/DD-hh:mm:ss の書式で日時を出力するには

$ date "+%Y/%m/%d-%H:%M:%S"

同じフォーマットをperlで表示するには

my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
$year += 1900;
$mon += 1;
print sprintf("%04d/%02d/%02d-%02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);

曜日を取得するには

$ date "+%w"

0-6の数字を出力する。0が日曜日。

明日の日付を取得するには

$ date --date "1 day" "+%Y-%m-%d"

--date オプションに渡す文字列はいろいろ書ける。

$ date --date "2 days" "+%Y-%m-%d"
$ date --date "1 day ago" "+%Y-%m-%d"
$ date --date "1 days ago" "+%Y-%m-%d" # 単数形複数形が間違っていても大丈夫
$ date --date "1 month" "+%Y-%m-%d"

UNIX時間を取得するには

## 現在日時
$ date +%s

## 1日前
$ date --date "1day ago" +%s

UNIX時間から日時を取得するには

--date オプションに渡す文字列として、数字の前に @ を付けると、
UNIX時間での指定になる。

$ date --date @1382282400
Mon Oct 21 00:20:00 JST 2013

日時を設定するには

## 9月4日12時17分に設定
$ sudo date -s "2013/09/04 12:17:00"

日付のフォーマットがよくわからないが、以下のフォーマットでもできた。

$ sudo date -s "2013-09-04T12:17:00"

あらかじめ sudo なしで実行してみて、日時のフォーマットが合っているかを確認するとよい。

月末かどうかをシェルスクリプトで判定するには

date -d day で翌日の日付を取得できるので、'+%d' というフォーマットで日だけにしてそれが1かどうかを見ればよい。

if [ `date -d day '+%d'` = '01' ]; then
    echo きょうは月末日
fi

ファイルのタイムスタンプ(更新日時)を取得するには

ls -l foo.txt でもファイルの情報を見ることができるが、更新日時に限定すれば、なぜかdateコマンドでも見ることができる。

$ date -r foo.txt
Tue Sep 29 14:15:04 JST 2015

もちろんフォーマットも指定できる。

$ date -r foo.txt "+%Y-%m-%d"
2015-09-29

シェルスクリプトの中で日付でループするには

以下のようなスクリプトで 2016-10-01 から 2016-12-31 までの日付が出力される

d="2016-10-01"

while [ "$d" != "2017-01-01" ]; do
    echo $d
    d=$(date +%F -d "$d 1 day")
done

bashなら以下のようにも書ける。

d="2016-10-01"

while [[ "$d" < "2017-01-01" ]]; do
    echo $d
    d=$(date +%F -d "$d 1 day")
done

以下の記事も参照。
連続した数字や日付や時刻を出力するには(seqコマンド)

このサイトは個人メモの集合です。
スポンサーリンク