[[lubridate]] で文字列や数値から日時オブジェクトを組み立てる関数は、`tz` 引数を省略するとデフォルトで UTC を返す。一方、[[Base R]] の `as.POSIXct()` は `tz` 引数を省略するとシステムロケール (macOS の日本語環境なら `Asia/Tokyo`) を採用する。 ```r ymd_hms("2026-05-14 10:30:00") #> [1] "2026-05-14 10:30:00 UTC" as.POSIXct("2026-05-14 10:30:00") #> [1] "2026-05-14 10:30:00 JST" ``` 同じ文字列を渡しても、両者が表す瞬間は 9 時間 (32,400 秒) ずれる。Base R と lubridate を混在させると、本来同じ時刻を指していたはずの値がこの差ぶんずれて保存され、後続の比較・計算・送信のすべてに誤差として伝播する。 ## 例外: 現在時刻を取る関数はシステムロケール lubridate でも `now()` と `today()` だけはシステムロケールを使う。「文字列・数値から日時を組み立てる」場面では UTC、「システムに現在時刻を聞く」場面ではロケール、という二段構えになっている。 ```r now() #> [1] "2026-05-14 15:02:22 JST" today() #> [1] "2026-05-14" ``` 両関数とも `tzone` 引数で任意のタイムゾーンを明示できるため、`now(tzone = "UTC")` のように書けば UTC で受け取れる。 ## 推奨運用: tz 引数を明示する lubridate でも Base R でも、タイムゾーン引数 (`tz` または `tzone`) を毎回明示すればこの差で事故は起きない。 実務では、他システム (BigQuery などの DWH や外部 API、CSV ファイル) と突き合わせるなら UTC 固定が安全で、ローカル時刻で表示したい場面のみ `"Asia/Tokyo"` を明示する運用が扱いやすい。 ```r ymd_hms("2026-05-14 10:30:00", tz = "Asia/Tokyo") #> [1] "2026-05-14 10:30:00 JST" as.POSIXct("2026-05-14 10:30:00", tz = "UTC") #> [1] "2026-05-14 10:30:00 UTC" ``` ## 関連ノート - **[応用]** [[dplyr の mutate() と lubridate の make_datetime() で日時列を作成する]]: lubridate の UTC デフォルト規約が `make_datetime()` を dplyr 連携で使う場面でそのまま効く実装例