Rの日時データ #2 - 文字列⇔日時オブジェクトの変換
はじめに
Rの日時データ[1]に関する記事#2です。
今回は文字列⇔日時オブジェクト[1:1]の変換手順についてです。
文字列と日時オブジェクト(POSIXct型のオブジェクト)の変換として、
- 変換方向(文字列→日時オブジェクト or 日時オブジェクト→文字列)
- 文字列に明示的にタイムゾーン情報があるか(あり(ISO8601形式) or なし)
によって、以下の4つの手順に分けて説明します。
タイムゾーン情報あり | タイムゾーン情報なし | |
---|---|---|
文字列→日時オブジェクト | 1 | 2 |
日時オブジェクト→文字列 | 3 | 4 |
1. 文字列→日時オブジェクト(タイムゾーン情報あり)
タイムゾーン情報が明示的に指定された文字列(ISO8601形式)を日時オブジェクト(POSIXct型のオブジェクト)に変換するには、#1で紹介したlubridate::ymd_hms
関数を使うと良いでしょう。
> lubridate::ymd_hms("2022-11-24T00:30:38+09:00")
[1] "2022-11-23 15:30:38 UTC"
> lubridate::ymd_hms("2022-11-24T00:30:38Z")
[1] "2022-11-24 00:30:38 UTC"
>
lubridate::ymd_hms
関数を使用することで、ISO8601形式であればどのタイムゾーンの文字列であっても問題なく変換することができます。
2. 文字列→日時オブジェクト(タイムゾーン情報なし)
タイムゾーンの指定がない場合は、必ず仕様を確認し、as.POSIXct
関数のtz
引数を指定することが必要です。
> as.POSIXct("2011-03-20 12:34:56", tz="UTC")
[1] "2011-03-20 12:34:56 UTC"
> as.POSIXct("2011-03-20 12:34:56", tz="Asia/Tokyo")
[1] "2011-03-20 12:34:56 JST"
>
tz
引数を指定しないと、#1で紹介したように、実行環境のシステムのタイムゾーンに依存した日時オブジェクトが作成されてしまいます。
> as.POSIXct("2011-03-20 12:34:56")
[1] "2011-03-20 12:34:56 JST"
>
3. 日時オブジェクト→文字列(タイムゾーン情報あり)
日時オブジェクト(POSIXct型のオブジェクト)からタイムゾーン情報ありのISO8601形式にするには、以下の3つの方法があります。用途と出力形式が微妙に異なるので、状況に応じて使い分けると良いでしょう。
format
/strftime
関数(%z
記法)
baseライブラリのformat
関数やstrftime
関数を使う方法です。
format
関数のtz
引数にタイムゾーンを指定し、フォーマット文字列に%z
を指定することで、タイムゾーンを示す文字列(+0900
)を追加できます。但し、ここで追加される+0900
はISO8601の基本形式と呼ばれるもの(:
が付いていないもの)になっている点に注意が必要です。また、UTCの場合にZ
でなく+0000
になってしまう点にも注意が必要でしょう。
> d <- as.POSIXct("2011-03-20 12:34:56", tz="Asia/Tokyo")
> format(d, "%Y-%m-%dT%H:%M:%S%z", tz="Asia/Tokyo")
[1] "2011-03-20T12:34:56+0900"
> format(d, "%Y-%m-%dT%H:%M:%S%z", tz="UTC")
[1] "2011-03-20T03:34:56+0000"
>
format
/strftime
関数(固定タイムゾーン文字列指定)
+0900
や+0000
でなく、+09:00
やZ
に変換したい場合には、あまり美しくないですが、フォーマット文字列に指定するしか無いようです。
> d <- as.POSIXct("2011-03-20 12:34:56", tz="Asia/Tokyo")
> format(d, "%Y-%m-%dT%H:%M:%S+09:00", tz="Asia/Tokyo")
[1] "2011-03-20T12:34:56+09:00"
> format(d, "%Y-%m-%dT%H:%M:%SZ", tz="UTC")
[1] "2011-03-20T03:34:56Z"
>
lubridate::format_ISO8601
関数
日時オブジェクト(POSIXct型のオブジェクト)で保持されたタイムゾーンに応じて出力されるタイムゾーンを変えたい場合は、lubridate::format_ISO8601
関数を使うと良いでしょう。
> d <- as.POSIXct("2011-03-20 12:34:56", tz="Asia/Tokyo")
> format_ISO8601(d, usetz = TRUE)
[1] "2011-03-20T12:34:56+0900"
> d <- with_tz(d, tzone = "UTC")
> format_ISO8601(d, usetz = TRUE)
[1] "2011-03-20T03:34:56+0000"
>
動作はフォーマット文字列に%z
を使用した場合と同じで、:
が付いてなく、Z
に変換されない点に注意が必要です。
4. 日時オブジェクト→文字列(タイムゾーン情報なし)
"2011-03-20 12:34:56"のようなタイムゾーン情報なしの文字列に変換するには、baseライブラリのformat
関数やstrftime
関数を使えば可能です。
> d <- as.POSIXct("2011-03-20 12:34:56", tz="Asia/Tokyo")
> format(d, "%Y-%m-%d %H:%M:%S", tz="Asia/Tokyo")
[1] "2011-03-20 12:34:56"
> format(d, "%Y-%m-%d %H:%M:%S", tz="Europe/Paris")
[1] "2011-03-20 04:34:56"
> strftime(d, "%Y-%m-%d %H:%M:%S", tz="Asia/Tokyo")
[1] "2011-03-20 12:34:56"
> strftime(d, "%Y-%m-%d %H:%M:%S", tz="Europe/Paris")
[1] "2011-03-20 04:34:56"
>
この場合も、tz
引数は付けたほうがコードの意図が明確になって親切だと思います。
以下のように、tz
引数無しで呼び出した場合、タイムゾーンに依存せず時刻の情報のみで文字列が生成されるようです。
> d <- as.POSIXct("2011-03-20 12:34:56", tz="Asia/Tokyo")
> format(d, "%Y-%m-%d %H:%M:%S")
[1] "2011-03-20 12:34:56"
> d <- as.POSIXct("2011-03-20 12:34:56", tz="UTC")
> format(d, "%Y-%m-%d %H:%M:%S")
[1] "2011-03-20 12:34:56"
>
まとめ
今回は、文字列⇔日時オブジェクトの変換について4つの場合に分けて紹介しました。
次回の#3は、csvファイルの読み書きと日時オブジェクト(POSIXct型のオブジェクト)について書きたいと思います。
Discussion