[[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 連携で使う場面でそのまま効く実装例