概要
- Date-time オブジェクトのタイムゾーン変換がよく分からなかった.
- 実はちゃんとリファレンスに書いてあった.
詳細
文字列を日付として取り込む場合, as.POSIX* を使う(strptime()
関数というのもある). さらにこのとき, タイムゾーンを指定すれば別の標準時間に変換して読み込んでくれる.
# タイムゾーン指定なしの場合ローカルのタイムゾーンになる. as.POSIXlt(x="2015-01-11 00:00:01", format="%Y-%m-%d %H:%M:%S") as.POSIXct(x="2015-01-11 00:00:01", format="%Y-%m-%d %H:%M:%S")
結果はいずれも
[1] "2015-01-11 JST"
タイムゾーンを tz=
で指定すると,
as.POSIXlt(x="2015-01-11 00:00:01", format="%Y-%m-%d %H:%M:%S", tz="Japan") as.POSIXct(x="2015-01-11 00:00:01", format="%Y-%m-%d %H:%M:%S", tz="Japan")
結果はいずれも,
[1] "2015-01-11 00:00:01 JST"
では他のタイムゾーンにすると?
as.POSIXlt(x="2015-01-11 00:00:01", format="%Y-%m-%d %H:%M:%S", tz="Jamaica") as.POSIXct(x="2015-01-11 00:00:01", format="%Y-%m-%d %H:%M:%S", tz="Jamaica")
結果はいずれも,
[1] "2015-01-11 00:00:01 EST"
なお, 指定できるタイムゾーンの名称は環境依存なので, OlsonNames()
で使用可能な名称を確認したほうがいい. 日本の場合, Japan
と Asia/Tokyo
が使用できるが, いずれも出力時は "JST" 表記になる.
問題はここからで, 一旦タイムゾーンを指定した時刻を別のタイムゾーンに変換するには?
as.POSIXlt()
で再度 tz=
を指定してみた場合,
test <- as.POSIXlt(x="2015-01-01 00:00:01", format="%Y-%m-%d %H:%M:%S", tz="Japan") as.POSIXlt(test, tz="Jamaica")
以下のように変わらないので不正解.
[1] "2015-01-01 00:00:01 JST"
正解は以下
as.POSIXlt(as.POSIXct(test, tz="Japan"),tz="Jamaica")
[1] "2014-12-31 10:00:01 EST"
一旦 as.POSIXct()
にかけると, タイムゾーン表記が変わるが, 時刻は変わらない (言い換えるなら, 額面通りの時刻をそのタイムゾーンでの時刻とみなす). これにもう一度 as.POSIXlt()
を通すと, 指定したタイムゾーンの時刻に変換される. なんとなく冗長な感じだが, これが正しい方法らしい. よそのサイト
有効なWikiNameではありません - RjpWiki では 『"POSIXct" オブジェクトはデータフレーム中で使うのにより便利であるが,"POSIXlt" オブジェクトはより可読性が高い.』というふうに書いてあったので, それが違いの本質かと誤解していたが, こういう用途があった.
という話, 実は公式マニュアルに書いてあった.
Character input is first converted to class "POSIXlt" by strptime: numeric input is first converted to "POSIXct". Any conversion that needs to go between the two date-time classes requires a time zone: conversion from "POSIXlt" to "POSIXct" will validate times in the selected time zone. One issue is what happens at transitions to and from DST, for example in the UK
as.POSIXct(strptime("2011-03-27 01:30:00", "%Y-%m-%d %H:%M:%S")) as.POSIXct(strptime("2010-10-31 01:30:00", "%Y-%m-%d %H:%M:%S"))
are respectively invalid (the clocks went forward at 1:00 GMT to 2:00 BST) and ambiguous (the clocks went back at 2:00 BST to 1:00 GMT).
英語でも面倒臭がらずに公式マニュアルをちゃんと読みましょう, というオチでした. "ct" が calendar time で, "lt" が local time らしいので, ct, lt の意味を覚えておけば混乱しないと思う. なお, Sys.time()
関数は POSIXct オブジェクトを返すので, as.POSIXlt(Sys.time(), tz="Jamaica")
のようにすぐに別のタイムゾーンに変換できる.
参考文献
- 奥村 晴彦 (2014) 時系列データ https://oku.edu.mie-u.ac.jp/~okumura/stat/timeseries.html
- Rjp Wiki (2012) 日付・時間関数Tips大全 http://www.okada.jp.org/RWiki/?%C6%FC%C9%D5%A1%A2%BB%FE%B4%D6%B4%D8%BF%F4Tips%C2%E7%C1%B4
- R Core Team (2014). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. http://www.R-project.org/