UNIX/Linuxの部屋 dateコマンドの使い方

TOP UNIX/Linuxの部屋 UNIX/Linuxコマンド一覧 用語集 新版 由来/読み方辞書 環境変数マニュアル Cシェル変数 システム設定ファイル システムコール・ライブラリ ネットワークプログラミングの基礎知識 クラウドサービス徹底比較・徹底解説




コマンド date 現在の時刻 (日時) を表示・設定する このエントリーをはてなブックマークに追加

UNIX/Linux の date コマンドは、現在の日付・日時を表示したり、指定のフォーマットで年月日・時分秒・曜日・タイムゾーンなどを表示するコマンドである。前日・翌日・先月・翌月や、N日後などの時刻計算を行うこともできる。また、root であれば現在時刻を設定することもできる。


date コマンドの基本的な使い方
引数なしで実行すると、現在の時刻を表示する。
% date
Sun Oct 10 10:38:28 JST 1999
-u オプションを与えると、世界標準時で表示する。
% date -u
Sun Oct 10 01:38:58 GMT 1999

任意フォーマットでの日時・時刻表示
「+」のあとに文字列を指定すると、任意のフォーマットで表示できる。
% date "+%Y/%m/%d %H:%M:%S"
1997/02/25 06:04:41
フォーマットの書式は以下の通り。より詳しい書式は、strftime(3) を参照してほしい。
%Y 年 (4桁表示)
%y 年 (2桁表示)
%m 月 (2桁表示=ゼロパディング)
%d 日 (2桁表示=ゼロパディング)
%e 日 (ゼロパディングなし)
%h 月 (英語表示 Jan,Feb...)
%H 時 (2桁表示=ゼロパディング)
%M 分 (2桁表示=ゼロパディング)
%S 秒 (2桁表示=ゼロパディング)
%s UNIX時間 (epoch)。1970/01/01 00:00:00 からの経過秒数
% date +%s
1490278214
%n 改行
%N ナノ秒 (000000000〜999999999。ゼロパディング)
ミリ秒・マイクロ秒が必要な場合は、桁を削るとよい。GNU date のみ。
% date "+%H:%M:%S.%N"
20:19:51.001562824
→ ナノ秒
% date "+%H:%M:%S.%N" | cut -c1-15
20:19:51.001562
→ マイクロ秒
% date "+%H:%M:%S.%N" | cut -c1-12
20:19:51.001
→ ミリ秒
%T 24時間表記の時刻 (%H:%M:%S と同じ)
%t タブ
%Z タイムゾーン
%% 「%」自体

なお、% 以外は好きに書いてよいので、
% date "+時刻は[[%Y/abc%mdef/%d]]です"
時刻は[[2017/abc03def/23]]です
と書いてもよい。

GNU date の場合、下記のようにゼロパディングを抑止できる。
% date '+%Y/%_m/%_d'
2017/ 3/23
→ アンダーバー指定で空白詰め
% date '+%Y/%-m/%-d'
2017/3/23
→ ハイフン指定でパディングしない

UNIX時間 (epoch) を日時に変換
BSD
% date -j -f "%s" 1490278214
2017年 3月23日 木曜日 23時10分14秒 JST
% date -r 1490278214
2017年 3月 23日 木曜日 23:10:14 JST
GNU date では先頭に "@" を付けることで、UNIX 時間とみなしてくれる。
% date -d @1490278214
2017年 3月 23日 木曜日 23:10:14 JST

BSD 系の日付・時刻の計算 (前日・翌日・n時間後・n日後・nヵ月後)
FreeBSD・NetBSD など、BSD 系において n 時間後、n 日後、n ヵ月後などの時刻を知りたい場合は -v オプションを使えばよい。
% date -v+1y (1年後の時刻を表示)
% date -v+2m (2ヵ月後の時刻を表示)
% date -v+3w (3週間後の時刻を表示)
% date -v+4d (4日後の時刻を表示)
% date -v+5H (5時間後の時刻を表示)
% date -v+6M (6分後の時刻を表示)
% date -v+7S (7秒後の時刻を表示)
過去に戻る場合はプラスをマイナスに変える。
% date -v-1y (1年前の時刻を表示)
% date -v-2m (2ヵ月前の時刻を表示)
% date -v-1d (前日の時刻を表示)
今から 1年後の 2日前の時刻は、-v を複数回指定して
% date -v+1y -v-2d
とする。

Linux 系の日付・時刻の計算 (前日・翌日・n時間後・n日後・nヵ月後)
Linux 系の場合、-d または --date オプションを使う。
未来
date -d '1 year' 1年後(翌年)
date --date '1 year' 1年後(翌年)
→ -d でも --date でも同じ
date --date '1 month' 1ヶ月後(翌月)
date --date '1 day' 1日後(翌日)
date --date '1 hour' 1時間後
date --date '1 minute' 1分後
date --date '1 sec' 1秒後
過去の場合は、マイナスを付けるか、末尾に ago を付ける。
date --date '-1 year' 1年前(前年)
date --date '1 year ago' 1年前(前年)
→ "-1 year" の代わりに "1 year ago" でもよい。
date --date '-1 month' 1ヶ月前(先月)
date --date '-1 day' 1日前(前日)
date --date '-1 hour' 1時間前
date --date '-1 minute' 1分前
date --date '-1 sec' 1秒前
date --date '-1 sec' 1秒前
今から 1年後の 2日前の時刻は、--date の後の引数に全部押し込む。ただし ago の位置が非常にわかりづらいので、"1 year -2 day" の書き方がよいのではないかと思う次第である。
% date --date '2 day ago 1 year'
% date --date '1 year 2 day ago'
% date --date '1 year -2 day'
とする。

時刻のパースと計算
"2017/03/23" などの、年月日時分秒などの文字列をパースさせる方法を説明する。何のためにパースさせるかというと、異なるフォーマットで表示するか、1ヶ月後などの日付計算をするためなので、その方法もあわせて提示する。

BSD date の場合。-f にてフォーマットを指定する。
% date -j -f "%Y/%m/%d" 2017/03/23
2017年 3月23日 木曜日 23時38分54秒 JST
% date -j -f "%Y/%m/%d %H:%M:%S" "2017/03/23 01:02:03"
2017年 3月23日 木曜日 01時02分03秒 JST
% date -j -v+1y -f "%Y/%m/%d" 2017/03/23 +%Y%m%d
→ 2017/03/23 の 1年後 (-v+1y) を、%Y%m%d (YYYYMMMDD) で表示

GNU date では、-d または --date オプションに、日付っぽい文字列を渡せばよい。
% date -d '2017/03/23'
2017年 3月 23日 木曜日 00:00:00 JST
% date -d "2017/03/23 01:02:03"
2017年 3月 23日 木曜日 01:02:03 JST
さらに日付計算も -d または --date にまとめて書けばよいので、下記のように簡単に書ける。
% date -d "2017/03/23 01:02:03 2 year"
2019年 3月 23日 金曜日 01:02:03 JST
→ 2年後 (2 year) を表示
% date -d "2017/03/23 01:02:03 1 year" "+%Y年%m月%d日(%a) %H時%M分%S秒"
2018年03月23日(金) 01時02分03秒
→ それを指定のフォーマットで表示
GNU date の場合、簡単なのはよいのだが、任意のフォーマットでのパースができないようだ。例えば RFC 3339 形式である "2001-02-03T04:05:06+09:00" は解釈できない。BSD date のように -f オプションでフォーマットを指定できないようだ。よって、sed 等でタイムゾーン部分を削るなどの対応が必要となる。

-v オプションも --date オプションも使えない場合
例えば Solaris の date では -v オプションも --date オプションも使えない。その場合はタイムゾーンを設定することで、ある程度までは対応できる (このような使い方はタイムゾーン本来の用途ではない)。

例えば日本時間は世界標準時間 GMT (≒UTC) より9時間早いので、
% date

% env TZ=JST-9 date
と等価である。よって、1日前 (24時間前) の日付を知りたければ -9+24=15 というタイムゾーンを設定すればよい。1日後 (24時間後) なら -9-24=-33 とすればよい。
% env TZ=JST+15 date (1日前の時刻を表示)
% env TZ=JST-33 date (1日後の時刻を表示)
タイムゾーンをプラスにすれば過去にさかのぼり、マイナスにすれば未来の時刻となることに注意。

date コマンドを使って現在時刻を設定することもできる。当然ながら時刻設定は root でないとできない。
# date 9803301445
⇒ 現在時刻を1998年3月31日14時45分に設定する。
# date 0632
⇒ 現在時刻を6時32分に設定する。日付は変更しない。

シェルスクリプトで時刻計算
下記はとりあえず sh + GNU date 版。BSD はそのうち書きます。

翌日の日付を YYYYMMDD 形式で取得。
tomorrow=`date +%Y%m%d --date "1 day"`

前日の日付を YYYYMMDD 形式で取得。
yesterday=`date +%Y%m%d --date "1 day ago"`

ファイル名に含まれる日付の前日を取得。
file_name='sample-20180313.txt'
file_date=`echo $file_name | sed 's/sample-\([0-9][0-9]*\).txt/\1/'`
file_next_date=`date +%Y%m%d --date "$file_date 1 day"`
echo $file_next_date

現在日付から、その日付を含む10日前までの日付を YYYYMMDD で取得。
for i in `seq 0 9`; do
target_date=`date +%Y%m%d --date "$i day ago"`
echo $target_date
done

特定日付から、その日付を含む10日後までの日付を YYYYMMDD で取得。
startdate='20180301'
for i in `seq 0 9`; do
target_date=`date +%Y%m%d --date "$startdate $i day"`
echo $target_date
done

関連コマンド
ネットワークを利用して正確な時刻に設定するには ntpdate を使うとよい。
>> Linuxオンラインマニュアル(man) Linux date(1)
>> FreeBSDオンラインマニュアル(man) FreeBSD date(1)
>> Solaris10オンラインマニュアル(man) Solaris10 date(1)