0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Bash 4.2以降ではprintfでUNIX時間の取得と日常の日付への変換が簡単にできる

Posted at

はじめに

シェルスクリプトの互換性問題で意外と困るのが日付処理です。date コマンド自体は POSIX で規定されていますが共通で使えるオプションが少なく Linux (GNU) と macOS (BSD) 間での互換性は低いです。

そこで日付処理の選択肢の一つとして使える bash の printf の機能を紹介します。bash 4.2 以上(または ksh93)を使うことが前提となりますがシェルに搭載されている機能であるため date コマンドに依存することなく使用することができます。注意事項として macOS でデフォルトでインストールされている bash は 3.2.57 とバージョンが低いので Homebrew などで最新版をインストールする必要があります。

使い方

引数を何も指定しない場合、現在の日時が表示されます。

$ printf '%(%F %T)T\n'
2021-08-15 16:13:33

引数には UNIX 時間を指定することができます。

$ printf '%(%F %T)T\n' 1629011613
2021-08-15 16:13:33

また特殊な値として -1 (現在時刻) と -2 (シェルスクリプトを実行した時刻) を指定することができます。

$ printf '%(%F %T)T\n' -1
2021-08-15 16:22:47
$ printf '%(%F %T)T\n' -2
2021-08-15 16:20:25

書式

日付の書式は strftime と同じ datefmt書式が利用可能です。(注意 全て問題なく使用できるかは検証していません)

$ printf '%(%s)T\n' # UNIX タイム
1629012592

$ printf '%(%Y/%m/%d %H:%M:%S)T\n'
2021/08/15 16:32:18

変数への割当

UNIX 時間を取得できたならば、それを変数に代入したくなることでしょう。では現在の UNIX 時間を変数へ代入・・・

now=$(printf '%(%s)T')

っと、このコードは書かないでください。コマンド置換はサブシェルが生成される為遅いです。こちらが推奨される方法です。

printf -v now '%(%s)T' 

ちなみに 100 倍以上の差があります。

$ time for i in $(seq 10000); do printf -v now '%(%s)T'; done

real	0m0.090s
user	0m0.058s
sys	0m0.032s

$ time for i in $(seq 10000); do now=$(printf '%(%s)T'); done

real	0m12.482s
user	0m8.382s
sys	0m4.985s

さいごに

さて、実はこの日付出力機能は ksh93 の情報を調べていて気づきました。今までも目にしてた記憶はあるのですが読み飛ばしていましたね。bash の日付出力の機能の残念なところは、日常の日付から UNIX 時間への変換ができないということです。

$ bash -c "printf '%(%s)T\n' '2021-08-15 16:13:33'"
bash: line 1: printf: 2021-08-15 16:13:33: invalid number
2021

$ # ksh93 ならできる
$ ksh -c "printf '%(%s)T\n' '2021-08-15 16:13:33'"
1629011613

いや、実に惜しい。これさえできればシェルだけで簡単に時間計算ができたのですが。

でも大丈夫、UNIX 時間と日常の日付の相互変換はシェル関数だけ(外部コマンド不要)で実装することができます(参照「シェルスクリプトでUNIX時間⇔日付の相互変換を行う関数(POSIX準拠)」)。UNIX 時間にさえ変換してしまえば、1 週間前の日付を計算するのも簡単なわけで、これらを組み合わせると外部コマンドを使用することなく現在の日付の取得と時間計算を行うことができます。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?