Lua#10 Luaで現在日時を取得して整形表示する

Last modified: 2021-07-27

おみくじ/複数の文字列の内の1つを無作為に選択する” で扱ったos.time()は単一の数値の形で現在日時を取得するもので、乱数を扱う際には便利だが、人間が日時として扱えるものではない。

ここでは、人間が扱いやすい形で現在日時を取得する方法を扱う。

解説

Luaで現在日時を文字列または整形可能な形式で取得するにはos.date()を呼び出す。

この関数は呼び出し時の引数の指定によって結果の受け取り方と扱い方が異なるので、以下それぞれについてを扱う。

整形済みの現在日時の文字列を得る

os.date()を引数なしで呼び出すと、現在動作しているOSの現在日時を整形した文字列が得られる。

> os.date()
-- "Tue Jul 27 12:34:56 2021" の形式で現在日時が表示される

この書式はロケール(地域)設定の影響を受ける。

OSの言語/地域の設定が英語以外に設定されている場合はos.setlocale()を呼び出すことでOSのロケール設定に基づいた結果が得られるようにできる。

空文字列を指定してos.setlocale('')という形で呼び出すと、日時の表記以外も含めてOS上の全てのロケール設定をLuaのプログラム内で適用できる。

-- 日本語に設定されたLinux上で実行した場合の例

> os.setlocale('')
-- "ja_JP.UTF-8" などの現在のロケール名が表示されるがここでは使用しない

> os.date()
-- "2021年07月27日 12時34分56秒" の形式で現在日時が表示される

書式を指定して現在日時の文字列を得る

C言語のstrftime()関数における書式指定文字列を引数として与えた場合、それに基づいた書式で結果が得られる。

これについても、書式指定文字列の中にロケールに依存した結果(曜日や月の名前など)を返す指定の文字列(例:%a)を含んだ場合、得られる結果はロケール設定の影響を受ける。

-- 日本語に設定されたLinux上で実行した場合の例

> os.date('%Y/%m/%d(%a) %H:%M:%S')
-- "2021/07/27(Tue) 12:34:56" の形式で現在日時が表示される

> os.setlocale('')
-- "ja_JP.UTF-8" などの現在のロケール名が表示されるがここでは使用しない

> os.date('%Y/%m/%d(%a) %H:%M:%S')
-- "2021/07/27(火) 12:34:56" の形式で現在日時が表示される

年や月などの個別の数値を含んだ連想配列を得る

年や月などの各要素を数値として取得したい場合、*tという文字列を渡すことで連想配列としてのテーブルの形で現在日時が得られる。

> d = os.date('*t')
-- "d" に結果が入る

> d.year
-- 西暦年が表示される

> d['hour']
-- 現在時刻の何時台かの値が表示される

要素名と値は以下のようになる。

要素名
year 西暦年
month 月 [1-12]
day 月の中の日 [1-31]
wday 曜日 [日曜=1, 月曜=2, … 金曜=6, 土曜=7]
hour 時 [0-23]
min 分 [0-59]
sec 秒 [0-611]

wdayは他の言語では “日曜の0から土曜の6まで” という形をとるが、Luaの添え字は1からなのでこの並びとなっている。

コード例

以上の挙動を確認するための例が以下となる。

[任意]ファイル名:010_date.lua エンコーディング:UTF-8
#! /usr/bin/lua
-- -*- coding: utf-8 -*-

--[[--  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
動作確認バージョン: 5.4, JIT2.1
--  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --]]

-----
----- 現在の日時を取得して整形表示
-----

do
    -- os.date()から得られる日時の書式や曜日名などが
    -- システムのロケールに合ったものになるようにする
    -- 次の行の書き方は日時関係以外のロケール設定も含めて設定
    os.setlocale('')
    -- 次の行は日時関係のみを "ja_JP.UTF-8" に設定する書き方
    --os.setlocale('ja_JP.UTF-8', 'time')

    -- os.date()で日時を整形しやすい形で取得する
    -- 引数を付けないと西暦年/月/日/時/分/秒をまとめた文字列が得られる
    -- 単一の数値を返すos.time()とは異なる
    local d = os.date()                              -- 戻り値 "d" は文字列型
    print(('os.date() -> %s'):format(d))

    -- 書式をC言語のstrftime()と同様の指定で行う場合
    d = os.date('%Y/%m/%d(%a) %H:%M:%S')             -- 戻り値 "d" は文字列型
    print(('os.date("%%Y/%%m/%%d(%%a) %%H:%%M:%%S") -> %s'):format(d))

    -- 連想配列のテーブルとして結果を得る場合は "*t" を指定
    d = os.date('*t')                                -- 戻り値 "d" はテーブル型
    -- 曜日を示す要素 "wday" は数値で得られるので文字で表すために配列を用意
    -- これは日本語で書いているのでロケール設定の影響を受けない
    local wday = {'日', '月', '火', '水', '木', '金', '土'}
    -- "." を用いて各要素を取り出し、整形して表示
    print(
        ('%04d/%02d/%02d(%s) %02d:%02d:%02d'):format(
            d.year, d.month, d.day, wday[d.wday], d.hour, d.min, d.sec))
    -- 角括弧を用いて各要素を取り出し、整形して表示
    print(
        ('%04d/%02d/%02d(%s) %02d:%02d:%02d'):format(
            d['year'], d['month'], d['day'], wday[d['wday']],
            d['hour'], d['min'], d['sec']))
end

-- 終了

下は実行結果の例。実行したときの日時によって表示内容は異なる。

os.date() -> 2021年07月27日 12時34分56秒
os.date("%Y/%m/%d(%a) %H:%M:%S") -> 2021/07/27(火) 12:34:56
2021/07/27(火) 12:34:56
2021/07/27(火) 12:34:56
  • 使用したバージョン
    • Lua 5.4.2
    • LuaJIT 2.1.0 Beta 3

  1. うるう秒を扱うため ↩︎