Slide 1

Slide 1 text

タイムゾーンの奥地は 思ったよりも闇深いかもしれない 2025-04-12 スー | PHP Conference Odawara 2025 1

Slide 2

Slide 2 text

所属 株式会社TechBowl 何やってる? 「TechTrain」というサービスで反復横跳びし続けてい る何でも屋さん(Laravel, Next.js, AWS, etc...) 2025-04-12 スー | PHP Conference Odawara 2025 2

Slide 3

Slide 3 text

本題に入っていく前に・・・ 2025-04-12 スー | PHP Conference Odawara 2025 3

Slide 4

Slide 4 text

Q. そもそもタイムゾーンってそんなに大事・・・? 2025-04-12 スー | PHP Conference Odawara 2025 4

Slide 5

Slide 5 text

A. 大事ですよ! 2025-04-12 スー | PHP Conference Odawara 2025 5

Slide 6

Slide 6 text

雰囲気実装を少し抜け出そう!RFCからPHPの実装 までを考えるタイムゾーンとサマータイム!!! 2025-04-12 スー | PHP Conference Odawara 2025 6

Slide 7

Slide 7 text

他に例えばですが 2025-04-12 スー | PHP Conference Odawara 2025 7

Slide 8

Slide 8 text

面談マッチングして面談するようなサービス サービス特性だけではないトラブルもおきます 2025-04-12 スー | PHP Conference Odawara 2025 8

Slide 9

Slide 9 text

SSL証明書が有効ではなくなる可能性です (一撃がデカすぎる) 2025-04-12 スー | PHP Conference Odawara 2025 9

Slide 10

Slide 10 text

どうです? 聴きたくなったのではないでしょうか・・・? (ガクブル) 2025-04-12 スー | PHP Conference Odawara 2025 10

Slide 11

Slide 11 text

そのほかありそうなこと 「ログの時刻がズレてる?該当ログがないんだけど・・・」 「海外ユーザー向け機能で決済の日時がおかしい?」 「なんかセッションが切れるログインがある」 2025-04-12 スー | PHP Conference Odawara 2025 11

Slide 12

Slide 12 text

今日のゴール タイムゾーンとは? 時刻同期がそもそもどういうプロトコルの元動いているのかを知る OSごとのタイムゾーン管理の違いがどうなっているのか? タイムゾーンデータ更新の重要性を知る 2025-04-12 スー | PHP Conference Odawara 2025 12

Slide 13

Slide 13 text

タイムゾーンの基本を復習 2025-04-12 スー | PHP Conference Odawara 2025 13

Slide 14

Slide 14 text

2025-04-12 スー | PHP Conference Odawara 2025 14

Slide 15

Slide 15 text

タイムゾーンはどう決まるのか? 地球を24の区域に分割(経度15度ごと) 国や地域の政治的決定が影響 夏時間の採用も政治的決定によるもの IANAタイムゾーンデータベースで管理 2025-04-12 スー | PHP Conference Odawara 2025 15

Slide 16

Slide 16 text

IANAタイムゾーンデータベースって何? タイムゾーンの正式なデータベース 「Asia/Tokyo」「Europe/Paris」などの地域ベースの識別子 歴史的な変更も含む 年に数回更新される ← テストに出ます 2025-04-12 スー | PHP Conference Odawara 2025 16

Slide 17

Slide 17 text

変更の例を試しに出すと 2025-04-12 スー | PHP Conference Odawara 2025 17

Slide 18

Slide 18 text

2025-04-12 スー | PHP Conference Odawara 2025 18

Slide 19

Slide 19 text

Q.その変更をどういう形式で どう管理しているんだっけ? 2025-04-12 スー | PHP Conference Odawara 2025 19

Slide 20

Slide 20 text

2025-04-12 スー | PHP Conference Odawara 2025 20

Slide 21

Slide 21 text

OSごとにはどういう形式? データフォーマット: Linux/macOS: 標準的なtzfileフォーマット Windows: 独自形式(Time Zone Information Registry Format) 識別子の違い: Linux/macOS: "Asia/Tokyo" (IANA形式) Windows: "Tokyo Standard Time" (Windows独自形式) 2025-04-12 スー | PHP Conference Odawara 2025 21

Slide 22

Slide 22 text

OSごとにどこにあるのか? 2025-04-12 スー | PHP Conference Odawara 2025 22

Slide 23

Slide 23 text

Linux /usr/share/zoneinfo/ ディレクトリにデータ /etc/localtime へのシンボリックリンクで設定 tzdata パッケージで更新 # タイムゾーン設定確認 ls -la /etc/localtime # タイムゾーン設定変更 sudo timedatectl set-timezone Asia/Tokyo 2025-04-12 スー | PHP Conference Odawara 2025 23

Slide 24

Slide 24 text

Windows レジストリで管理 Windowsアップデートで更新 NTPサーバーとの同期 # PowerShellでタイムゾーン確認 Get-TimeZone # タイムゾーン変更 Set-TimeZone -Id "Tokyo Standard Time" 2025-04-12 スー | PHP Conference Odawara 2025 24

Slide 25

Slide 25 text

macOS /usr/share/zoneinfo/ ディレクトリ(Linuxと類似) システム環境設定からも変更可能 OSアップデートで更新 # タイムゾーン確認 sudo systemsetup -gettimezone # タイムゾーン変更 sudo systemsetup -settimezone Asia/Tokyo 2025-04-12 スー | PHP Conference Odawara 2025 25

Slide 26

Slide 26 text

Q. IANAの形式にWindows従ってるんですか? 2025-04-12 スー | PHP Conference Odawara 2025 26

Slide 27

Slide 27 text

Q. 当然従ってくれてますよね!?!?!?!? 2025-04-12 スー | PHP Conference Odawara 2025 27

Slide 28

Slide 28 text

Q. ね!?!?!?!?!?!?!?!? 2025-04-12 スー | PHP Conference Odawara 2025 28

Slide 29

Slide 29 text

A. いいえ。独自形式があります。 2025-04-12 スー | PHP Conference Odawara 2025 29

Slide 30

Slide 30 text

2025-04-12 スー | PHP Conference Odawara 2025 30

Slide 31

Slide 31 text

たくさんの方が変換に倒れており Windowsの方がいらっしゃいましたら、注意が必要 2025-04-12 スー | PHP Conference Odawara 2025 31

Slide 32

Slide 32 text

タイムゾーンの情報って どういうルールで日時を同期してるの? 2025-04-12 スー | PHP Conference Odawara 2025 32

Slide 33

Slide 33 text

時刻情報の同期とNTP Network Time Protocol (NTP)は時刻同期の標準プロトコル 階層化されたサーバー群(ストラタム)で構成 インターネット上の原子時計と同期 ミリ秒単位の精度で時刻を同期 2025-04-12 スー | PHP Conference Odawara 2025 33

Slide 34

Slide 34 text

NTPサーバーの階層 ストラタム0: 原子時計・GPS ストラタム1: 直接接続するサーバー ストラタム2: ストラタム1に接続するサー バー 一般的にはストラタム3〜4を利用 2025-04-12 スー | PHP Conference Odawara 2025 34

Slide 35

Slide 35 text

NTPにおける大問題 - 2036年問題 1900年1月1日 0時0分0秒 (UTC)を起点とする 「何秒たったか」を積算する32ビットの積算秒数で表現する 「およそ2の32乗秒」までしか計算ができないため、42億9496万7295秒までしか 表現ができず、起点から42億9496万7295秒経過 2036年2月7日 6時28分15秒 (UTC) の次の秒、2036年2月7日 6時28分16秒には桁 あふれを起こす 「新たな起点になった」とリセットされてしまい、NTPが誤動作すると予想する 2025-04-12 スー | PHP Conference Odawara 2025 35

Slide 36

Slide 36 text

2036年問題の対策 1. NTPサーバが送信するデータを64ビット整数にする → 扱う西暦3000億年使える 2. 受信側でうまくやる → オーバーフローしたら、受け手側で未来の時間として扱 う 2025-04-12 スー | PHP Conference Odawara 2025 36

Slide 37

Slide 37 text

システムレベルの2036年問題の対策 NTPデーモン(ntpd, chronyd)を最新バージョンに保つ NTPv4(64ビット対応)を使用するサーバーを参照する設定に更新 2025-04-12 スー | PHP Conference Odawara 2025 37

Slide 38

Slide 38 text

PHPアプリケーションでの2036年問題の対策 PHPは内部的に64ビットタイムスタンプを使用しているが、OSの時計に依存 重要なシステムでは必要な場合は、外部タイムサーバーと直接比較する仕組みを 実装 時刻に依存する重要処理では絶対時間を使用し、許容範囲を設定する 2025-04-12 スー | PHP Conference Odawara 2025 38

Slide 39

Slide 39 text

NTPに従っているシステムは どのタイミングで同期してる? 2025-04-12 スー | PHP Conference Odawara 2025 39

Slide 40

Slide 40 text

日時同期のタイミング Linux: ntpdやchronydサービスで常時または定期的に同期 Windows: デフォルトで週に1回、手動設定で変更可能 macOS: 起動時と定期的(デフォルトでは1時間ごと)に同期 PHPはOSの時計に依存するため、OSの同期設定が重要 2025-04-12 スー | PHP Conference Odawara 2025 40

Slide 41

Slide 41 text

コンテナ環境での時刻同期 Dockerコンテナは通常ホストマシンの時刻を継承 Kubernetesでは各ノードがNTP同期を担当 コンテナ内でのntpdの実行は一般的に非推奨 タイムスタンプの精度に依存するアプリでは注意が必要 2025-04-12 スー | PHP Conference Odawara 2025 41

Slide 42

Slide 42 text

NTP設定と確認方法 # Linuxで現在のNTP状態確認 timedatectl status # NTPサーバーリストの確認(Linux, macOS) cat /etc/ntp.conf # server time.asia.apple.com ← macOSの場合 # Windowsで同期設定確認 w32tm /query /status # 手動での時刻同期(Linux) sudo ntpdate pool.ntp.org とこんなふうに確認できます! ぜひお手元でmacOSの部分を試してみてください! 2025-04-12 スー | PHP Conference Odawara 2025 42

Slide 43

Slide 43 text

ここからは時刻同期の トラブルシューティングの話 そもそも触る人ー? 2025-04-12 スー | PHP Conference Odawara 2025 43

Slide 44

Slide 44 text

いなければスキップ 2025-04-12 スー | PHP Conference Odawara 2025 44

Slide 45

Slide 45 text

時刻同期の問題とトラブルシューティング NTPサーバーへの接続失敗 ファイアウォールによるNTPポート(UDP 123)のブロック 大幅な時刻ずれによる段階的補正 仮想環境特有の時刻ドリフト問題 2025-04-12 スー | PHP Conference Odawara 2025 45

Slide 46

Slide 46 text

同期エラーの検出方法 # Linuxでのログ確認 journalctl -u systemd-timesyncd grep -i ntp /var/log/syslog # Windowsでの診断 w32tm /query /status w32tm /stripchart /computer:pool.ntp.org /samples:5 # ntpstatコマンド(要インストール) ntpstat ntpq -p 2025-04-12 スー | PHP Conference Odawara 2025 46

Slide 47

Slide 47 text

同期エラーの判定基準 接続状態: NTPサーバーに到達できない No server suitable for synchronization found Stratum値が16(同期未確立) 僕は本番で出会ったことはないので、もし戦士の方がいらっしゃいましたら 教えてください 2025-04-12 スー | PHP Conference Odawara 2025 47

Slide 48

Slide 48 text

同期エラーの判定基準 時刻ずれ: オフセット値が大きすぎる 一般的に100ms以上は要注意 ミッションクリティカルシステムでは10ms以上で警告 2025-04-12 スー | PHP Conference Odawara 2025 48

Slide 49

Slide 49 text

同期エラーの判定基準 同期状態フラグ: unsynchronised または unreachable w32tm /query /status で同期状態が unsynchronized ntpstat で "unsynchronised" と表示 高いjitter値: 時刻値の揺らぎが大きい 通常は数msが正常、100ms以上で問題の可能性 2025-04-12 スー | PHP Conference Odawara 2025 49

Slide 50

Slide 50 text

スキップはここまで! 2025-04-12 スー | PHP Conference Odawara 2025 50

Slide 51

Slide 51 text

ここまでで話したこと タイムゾーンのルールの話 日時同期の話(NTP) [optional] 日時同期エラーのトラブルシューティング 2025-04-12 スー | PHP Conference Odawara 2025 51

Slide 52

Slide 52 text

ここからいよいよタイムゾーンのファイルの中身の 話 2025-04-12 スー | PHP Conference Odawara 2025 52

Slide 53

Slide 53 text

タイムゾーンファイルの実体 次の3つからなります tzfile形式 ヘッダー構造 データセクション 2025-04-12 スー | PHP Conference Odawara 2025 53

Slide 54

Slide 54 text

タイムゾーンファイルの実体 tzfile形式 バイナリ形式でタイムゾーン情報を格納 /usr/share/zoneinfo/ 以下の各ファイル 2025-04-12 スー | PHP Conference Odawara 2025 54

Slide 55

Slide 55 text

タイムゾーンファイルの実体 ヘッダー構造 マジックナンバー "TZif" バージョン識別子 (v1, v2, v3) 64ビットタイムスタンプ対応(v2以降) 2025-04-12 スー | PHP Conference Odawara 2025 55

Slide 56

Slide 56 text

タイムゾーンファイルの実体 データセクション 移行時間 (transition times) タイプインデックス (indices) タイプテーブル (types with UTC offsets) 略称文字列 (abbreviation strings) うるう秒情報 (leap seconds) 2025-04-12 スー | PHP Conference Odawara 2025 56

Slide 57

Slide 57 text

2025-04-12 スー | PHP Conference Odawara 2025 57

Slide 58

Slide 58 text

tzfileの中身を見る # hexdumpでバイナリ内容を確認 hexdump -C /usr/share/zoneinfo/Asia/Tokyo # zdumpでタイムゾーンの移行時間を確認 zdump -v /usr/share/zoneinfo/Asia/Tokyo | head # PHPでタイムゾーン情報を詳細表示 php -r 'print_r((new DateTimeZone("Asia/Tokyo"))->getTransitions());' 2025-04-12 スー | PHP Conference Odawara 2025 58

Slide 59

Slide 59 text

PHPにおけるタイムゾーンの内部実装 TimeZoneクラス: C言語実装の timelib_tzinfo 構造体をラップ OS依存のTZデータベースをパース タイムゾーンキャッシュ: パフォーマンス向上のためメモリ内キャッシュを使用 date.timezone_cache の影響(php.ini設定) データの取得元: デフォルト: システムの /usr/share/zoneinfo PHP組み込みのデータ( timezonedb.h ) 拡張モジュール( timezonedb )からの上書き 2025-04-12 スー | PHP Conference Odawara 2025 59

Slide 60

Slide 60 text

PHP内部でのタイムゾーン処理フロー 1. 文字列識別子からの解決: $tz = new DateTimeZone('Asia/Tokyo'); → 内部で timelib_fetch_timezone_offset() 呼び出し 2. タイムスタンプの変換: $dt = new DateTime('2025-03-23 14:00:00', $tz); → timelib_get_time_zone_info() で特定時刻のオフセット計算 3. タイムゾーンプロパティの取得: $transitions = $tz->getTransitions(); 2025-04-12 スー | PHP Conference Odawara 2025 60

Slide 61

Slide 61 text

PHP-src: タイムゾーン実装の実態 ext/date/lib/timelib.h での定義: /* タイムゾーン情報を格納する構造体 */ typedef struct _timelib_tzinfo { char *name; /* タイムゾーン名 */ struct { uint32_t ttisgmtcnt; /* UTC/標準フラグの数 */ uint32_t ttisstdcnt; /* 標準/夏時間フラグの数 */ uint32_t leapcnt; /* うるう秒情報の数 */ uint32_t timecnt; /* 移行時間の数 */ uint32_t typecnt; /* タイプの数 */ uint32_t charcnt; /* 略称の文字数 */ } bit32; /* ... 移行時間やタイプデータへのポインタなど ... */ } timelib_tzinfo; 2025-04-12 スー | PHP Conference Odawara 2025 61

Slide 62

Slide 62 text

タイムゾーン情報の読み込み ext/date/lib/parse_tz.c から読み込み処理: /* タイムゾーンファイルを解析する関数 */ timelib_tzinfo *timelib_parse_tzfile( char *timezone, const timelib_tzdb *tzdb) { /* ... */ /* tzfileからデータを読み込み */ if (memcmp(buffer, "TZif", 4) == 0) { /* マジックナンバーの検証 */ version = *(buffer + 4); /* ... */ /* 移行時間の読み込み */ for (i = 0; i < header->timecnt; i++) { /* ... タイムスタンプとタイプインデックスの解析 ... */ } } /* ... */ } 2025-04-12 スー | PHP Conference Odawara 2025 62

Slide 63

Slide 63 text

php-src: DateTimeZone実装 ext/date/php_date.c からのPHPクラスインターフェース: /* DateTimeZoneクラスのメソッドテーブル */ static const zend_function_entry date_timezone_methods[] = { PHP_ME(DateTimeZone, __construct, arginfo_timezone_construct, ZEND_ACC_PUBLIC) PHP_ME(DateTimeZone, getName, arginfo_timezone_void, ZEND_ACC_PUBLIC) PHP_ME(DateTimeZone, getOffset, arginfo_timezone_getoffset, ZEND_ACC_PUBLIC) PHP_ME(DateTimeZone, getTransitions, arginfo_timezone_gettransitions, ZEND_ACC_PUBLIC) /* ... */ }; /* getTransitionsメソッドの実装 */ PHP_METHOD(DateTimeZone, getTransitions) { /* ... */ /* タイムゾーン情報からすべての移行情報を取得 */ for (i = 0; i < tz->timecnt; i++) { /* 各移行時間を配列として返す */ array_init(&element); add_assoc_long(&element, "ts", tz->trans[i]); add_assoc_string(&element, "time", timelib_time_to_string(dummy)); /* ... */ 2025-04-12 スー | PHP Conference Odawara 2025 63

Slide 64

Slide 64 text

date.timezone設定の解決順序 ini/php.ini-development の設定 [Date] ; タイムゾーン定義 ; http://php.net/date.timezone ;date.timezone = 2025-04-12 スー | PHP Conference Odawara 2025 64

Slide 65

Slide 65 text

date.timezone設定の解決順序 ext/date/php_date.c での解決順序: /* タイムゾーン設定の取得ロジック */ static timelib_tzinfo *get_timezone_info(void) { /* 1. システムのタイムゾーン環境変数 */ if ((env = getenv("TZ")) != NULL) { /* ... */ } /* 2. php.ini設定 */ if (DATEG(default_timezone) && *DATEG(default_timezone)) { /* ... */ } /* 3. PHPが推測したタイムゾーン */ if (!found_guess) { /* ... */ php_error_docref(NULL, E_WARNING, "date.timezone設定がありません。システムから自動検出が必要です。"); } 2025-04-12 スー | PHP Conference Odawara 2025 65

Slide 66

Slide 66 text

php-srcを追うのはここまで・・・! 2025-04-12 スー | PHP Conference Odawara 2025 66

Slide 67

Slide 67 text

タイムゾーン取り扱いの推奨される方法: php.ini で date.timezone を適切に設定する: サーバー環境全体で一貫したデ フォルトタイムゾーンを提供します。 DateTime および DateTimeZone オブジェクトを使用する: 特定のタイムゾーン で日時を扱いたい場合、これらのオブジェクトを使うことで、デフォルト設定に 依存せず、より明確かつ柔軟にタイムゾーンを管理できます。 2025-04-12 スー | PHP Conference Odawara 2025 67

Slide 68

Slide 68 text

あとは UTC 2025-04-12 スー | PHP Conference Odawara 2025 68

Slide 69

Slide 69 text

タイムゾーンのおすすめの取り扱いはわかった けど、トラブルの時のデバッグどうすんの? (特にコンテナ環境) 2025-04-12 スー | PHP Conference Odawara 2025 69

Slide 70

Slide 70 text

コンテナ環境での時刻確認 アプリケーションレベルでの確認 PHPのログに時刻情報を出力 error_log('Current time: ' . date('Y-m-d H:i:s.u T')); ヘルスチェックエンドポイントに時刻情報を追加 2025-04-12 スー | PHP Conference Odawara 2025 70

Slide 71

Slide 71 text

コンテナ環境での時刻確認 CloudWatch Logs Insights での分析 複数コンテナのログから時刻パターンを抽出 filter @message like /Current time:/ | parse @message "Current time: * " as timestamp | display timestamp ※ 出力形式によって上記のようなクエリでできるという例 2025-04-12 スー | PHP Conference Odawara 2025 71

Slide 72

Slide 72 text

コンテナ環境での時刻確認 ECS Exec(AWS CLI)の活用 aws ecs execute-command --cluster your-cluster \ --task your-task-id \ --container your-container \ --command "date" \ --interactive 2025-04-12 スー | PHP Conference Odawara 2025 72

Slide 73

Slide 73 text

DBとアプリケーションサーバーの時刻差確認 -- DBサーバーとアプリケーションサーバーの時刻差を秒単位で計算 SELECT TIMESTAMPDIFF( SECOND, FROM_UNIXTIME(?), -- PHPのtime()値をパラメータとして渡して実行 NOW() ) AS time_diff; 2025-04-12 スー | PHP Conference Odawara 2025 73

Slide 74

Slide 74 text

分散システムの時刻同期診断 サーバー間時刻差の可視化: // 各サーバーで実行して結果を比較 $server_time = date('Y-m-d H:i:s.u T'); $db_time = $pdo->query('SELECT NOW() AS time')->fetch()['time']; error_log("Server time: $server_time, DB time: $db_time"); 2025-04-12 スー | PHP Conference Odawara 2025 74

Slide 75

Slide 75 text

確認はまぁわかった。 ズレる対策はどうするの? 2025-04-12 スー | PHP Conference Odawara 2025 75

Slide 76

Slide 76 text

コンテナ環境での時刻ずれ対策 ホストレベルでのNTP設定 ECSホストインスタンスのNTP設定がコンテナに継承される EC2起動時のユーザーデータでNTP設定を強化 2025-04-12 スー | PHP Conference Odawara 2025 76

Slide 77

Slide 77 text

コンテナ環境での時刻ずれ対策 コンテナイメージの工夫 ベースイメージ選定時にタイムゾーンデータを確認 Dockerfileでタイムゾーン設定を明示 ENV TZ=Asia/Tokyo RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 2025-04-12 スー | PHP Conference Odawara 2025 77

Slide 78

Slide 78 text

良い子は、Asia/Tokyoにするなよ・・・!!! 2025-04-12 スー | PHP Conference Odawara 2025 78

Slide 79

Slide 79 text

コンテナ環境での時刻ずれ対策 監視とアラート CloudWatchカスタムメトリクスで時刻ずれを監視 X-Ray トレースでサービス間の時刻ずれを検知 2025-04-12 スー | PHP Conference Odawara 2025 79

Slide 80

Slide 80 text

もし頼れるインフラ担当がおられるチーム かつ、日時にこだわる必要があるプロダクトの場合 2025-04-12 スー | PHP Conference Odawara 2025 80

Slide 81

Slide 81 text

コンテナ環境での追加対策 ホストマシンの時刻同期を優先的に設定 Kubernetes環境: Node Problem Detector で時刻ずれを検知 アプリケーションレベルでの時刻検証 重要なワークロードには専用NTPサーバーの検討 サイドカーコンテナでの監視 時刻監視専用のコンテナを追加 Prometheusエクスポーターとして機能 2025-04-12 スー | PHP Conference Odawara 2025 81

Slide 82

Slide 82 text

まとめ 2025-04-12 スー | PHP Conference Odawara 2025 82

Slide 83

Slide 83 text

PHPとOSの関係 PHPは基本的にOSのタイムゾーンデータを使用 PHPのバージョンアップがタイムゾーン定義も更新 コンテナ環境では注意が必要 2025-04-12 スー | PHP Conference Odawara 2025 83

Slide 84

Slide 84 text

明日から取り組めるアクション 1. 全環境の php.ini とOS設定の整合性をチェックし、事情がなければできるだけ UTCにする 2. アプリの初期化処理で最悪UTCで取り扱えるように date_default_timezone_set('UTC') やデフォルトの設定を確認 3. 日時保存における処理についても理由がなければUTCを使おう 2025-04-12 スー | PHP Conference Odawara 2025 84

Slide 85

Slide 85 text

タイムゾーンデータは「生き物」だから闇を生 む・・・ タイムゾーンは政治的決定にかなり影響される とあるOSの標準には頭を悩ませるものの、IANAデータベースが標準 PHPではdate.timezone設定とDateTimeクラスが重要 開発ではUTC処理+表示時変換が基本 NTPは2038年問題があります!頭の隅に置く! 2025-04-12 スー | PHP Conference Odawara 2025 85

Slide 86

Slide 86 text

参考資料 PHP公式ドキュメント - タイムゾーン IANAタイムゾーンデータベース PHPでのDateTimeのベストプラクティス RFC 6557 - Procedures for Maintaining the Time Zone Database タイムゾーン呪いの書 (知識編) すごくありがたい記事でした! 2025-04-12 スー | PHP Conference Odawara 2025 86

Slide 87

Slide 87 text

ご静聴ありがとうございました! X: @suguru_ohki GitHub: @SuguruOoki 2025-04-12 スー | PHP Conference Odawara 2025 87

Slide 88

Slide 88 text

おまけ 2025-04-12 スー | PHP Conference Odawara 2025 88

Slide 89

Slide 89 text

NTPとPTPの比較 項目 NTP PTP 精度 ミリ秒〜マイクロ秒 マイクロ秒〜ナノ秒 実装 主にソフトウェア ハードウェア支援が望ましい 複雑さ 比較的シンプル より複雑 導入コスト 低い 高い(特にハードウェア対応機器) Webアプリでの利用 一般的 特殊用途(高頻度取引等)のみ PHPアプリケーションでは通常NTPで十分 マイクロ秒以上の精度が必要な場合はPTPを検討 2025-04-12 スー | PHP Conference Odawara 2025 89

Slide 90

Slide 90 text

政治的変更の実例 ロシアの永久夏時間採用と廃止(2011-2014) 2011年永久夏時間→2014年に標準時へ 結果: Sochi冬季オリンピック放送時間混乱 トルコの夏時間政策変更(2016) 突然の夏時間廃止決定(数日前通知) 結果: システム全体の混乱、予約システム障害 2025-04-12 スー | PHP Conference Odawara 2025 90

Slide 91

Slide 91 text

アルゼンチン・サンルイス州の事例(2009) アルゼンチン全土が夏時間を終了するなか、サンルイス州だけが独自の道を選択 2009年3月15日からUTC-4(西部アルゼンチン時間/WART)を採用 他の州とは異なるタイムゾーンで運用 結果: 国内取引システムでのタイムスタンプ不整合 予約システムの混乱 州境をまたぐ業務での日程調整問題 2025-04-12 スー | PHP Conference Odawara 2025 91

Slide 92

Slide 92 text

データ更新の必要性 OSのアップデート (zoneinfoファイルの更新) PHP: timezonedb PECL拡張のアップデート リスク: DST切替時刻のズレ、オフセット間違い タイムゾーンデータが古いと: 予約システムの時間ズレ バッチ処理タイミングの誤り 国際APIの認証エラー 2025-04-12 スー | PHP Conference Odawara 2025 92

Slide 93

Slide 93 text

タイムゾーンの更新について 2025-04-12 スー | PHP Conference Odawara 2025 93

Slide 94

Slide 94 text

タイムゾーンデータの更新内容 名称やエイリアスの追加/変更: 歴史的データの修正: うるう秒の情報: 2025-04-12 スー | PHP Conference Odawara 2025 94

Slide 95

Slide 95 text

タイムゾーンデータの更新内容 名称やエイリアスの追加/変更: 地域名の変更に伴う識別子の更新 互換性のための別名追加 例: Burma → Myanmar, Rangoon → Yangon 2025-04-12 スー | PHP Conference Odawara 2025 95

Slide 96

Slide 96 text

タイムゾーンデータの更新内容 歴史的データの修正: 過去の時刻切り替え日時の訂正 歴史研究により判明した情報の反映 2025-04-12 スー | PHP Conference Odawara 2025 96

Slide 97

Slide 97 text

タイムゾーンデータの更新内容 うるう秒の情報: 地球の自転速度変化に基づく調整 直近では2016年12月31日に追加 2025-04-12 スー | PHP Conference Odawara 2025 97

Slide 98

Slide 98 text

タイムゾーン更新の実際の影響 予期せぬ動作: 日付計算が突然変わる 特定地域のみでスケジュールタスクが異常動作 過去の日時データが不正確に変換される 2025-04-12 スー | PHP Conference Odawara 2025 98

Slide 99

Slide 99 text

タイムゾーン更新の実際の影響 影響範囲: OSレベル: /usr/share/zoneinfo の更新 ライブラリレベル: ICU、tzdata、phpのTimeZoneData アプリケーションレベル: キャッシュされたタイムゾーン情報 2025-04-12 スー | PHP Conference Odawara 2025 99

Slide 100

Slide 100 text

タイムゾーン更新の実際の影響 実例: ブラジルの夏時間廃止(2019年) 多くのシステムで混乱が発生 数百万ドル規模の経済的損失 2025-04-12 スー | PHP Conference Odawara 2025 100

Slide 101

Slide 101 text

タイムゾーン更新への対応方法 定期的な更新確認: IANAのTZデータ発表をウォッチ PHPとOS両方の更新が必要 2025-04-12 スー | PHP Conference Odawara 2025 101

Slide 102

Slide 102 text

タイムゾーン更新への対応方法 テスト方法: 異なるタイムゾーンでの日付計算テスト自動化 タイムゾーン更新前後での動作検証 2025-04-12 スー | PHP Conference Odawara 2025 102

Slide 103

Slide 103 text

タイムゾーン更新への対応方法 障害に強い設計: 絶対時間(UTC)での内部保存 局所的な表示時のみ変換 タイムゾーン情報の明示的な保存 2025-04-12 スー | PHP Conference Odawara 2025 103

Slide 104

Slide 104 text

PTP (Precision Time Protocol) IEEE 1588標準の高精度時刻同期プロトコル NTPよりさらに高精度(ナノ秒〜マイクロ秒レベル) 主な用途: 金融取引システム(高頻度取引) 産業オートメーション 電力網制御システム 通信ネットワーク 特徴: ハードウェアタイムスタンプ対応 ネットワーク遅延の非対称性を考慮 2025-04-12 スー | PHP Conference Odawara 2025 104

Slide 105

Slide 105 text

PHP内部でのタイムゾーン処理は、どのタイムゾーンをデフォルトとして使用するか を決定するための一連の優先順位に従います。以下にそのフローを説明します。 2025-04-12 スー | PHP Conference Odawara 2025 105

Slide 106

Slide 106 text

PHP内部でのタイムゾーン処理のフロー 1. date_default_timezone_set() 関数による設定: スクリプトの実行中に date_default_timezone_set() 関数が呼び出される と、その設定が最優先されます。 ここで指定されたタイムゾーンが、それ以降の date() 関数や DateTime オブジェクト(明示的にタイムゾーンが指定されない場合)などの日付・時 刻関連の処理で使用されるデフォルトのタイムゾーンになります。 例: date_default_timezone_set('Asia/Tokyo'); 2025-04-12 スー | PHP Conference Odawara 2025 106

Slide 107

Slide 107 text

2. php.ini ファイルの date.timezone 設定: date_default_timezone_set() がスクリプト中で呼び出されなかった場 合、PHPは php.ini ファイル内の date.timezone ディレクティブの設定 値を使用しようとします。 これはサーバー全体、または特定のディレクトリ/アプリケーションに対す るデフォルトのタイムゾーン設定として機能します。サーバー管理者が設定 するのが一般的です。 例 (php.ini内): date.timezone = "Asia/Tokyo" 現在の設定値は ini_get('date.timezone') で確認できます。 2025-04-12 スー | PHP Conference Odawara 2025 107

Slide 108

Slide 108 text

3. 環境変数 TZ (非推奨・限定的): 上記1と2の設定がない場合、一部の環境(主にUnix系システム)では環境変 数 TZ を参照することがあります。 しかし、PHPのドキュメントではこの方法への依存は推奨されておらず、動 作は環境によって異なる可能性があるため、通常は考慮すべきではありませ ん。 2025-04-12 スー | PHP Conference Odawara 2025 108

Slide 109

Slide 109 text

4. PHPによるシステム設定の推測 (非推奨・エラー発生): 上記1、2、3のいずれも利用できない場合、PHPはOS(オペレーティングシ ステム)のタイムゾーン設定を推測しようと試みることがありました (古い バージョン)。 しかし、この推測は信頼性が低く、また、近年のPHPバージョン (PHP 5.1.0 以降) では、 date_default_timezone_set() または php.ini でタイムゾー ンが明示的に設定されていない場合、日付/時刻関数を使用するたびに E_WARNING レベルのエラー(またはバージョンによっては E_NOTICE) が発生します。これは、開発者にタイムゾーン設定を強制するためです。 2025-04-12 スー | PHP Conference Odawara 2025 109

Slide 110

Slide 110 text

5. デフォルトのUTC: 上記1〜4のいずれの方法でもタイムゾーンが決定できず、かつエラー抑制な どが行われているような特殊な状況下では、最終的に UTC (協定世界時) が 使用される可能性があります。しかし、前述の通り、通常はその前に警告/エ ラーが発生するため、意図せずUTCになるケースは少ないはずです。 2025-04-12 スー | PHP Conference Odawara 2025 110

Slide 111

Slide 111 text

フローの要約: PHPは以下の順序でデフォルトタイムゾーンを決定します。 1. date_default_timezone_set() (スクリプト実行中の設定) 2. php.ini の date.timezone (サーバー/アプリケーション設定) 3. (警告/エラー発生) PHPがタイムゾーン設定を見つけられない場合、警告またはエ ラーが発生します。 4. (最終手段: UTC) 上記で決まらずエラーも発生しない特殊な場合、UTCになる可 能性があります。 推奨される方法: php.ini で date.timezone を適切に設定する: サーバー環境全体で一貫したデ フォルトタイムゾーンを提供します。 DateTime および DateTimeZone オブジェクトを使用する: 特定のタイムゾーン 2025-04-12 スー | PHP Conference Odawara 2025 111

Slide 112

Slide 112 text

format('Y-m-d H:i:s P') . "\n"; $londonTime = new DateTime('now', new DateTimeZone('Europe/London')); echo "Current time (London using DateTime): " . $londonTime->format('Y-m-d H:i:s P') . "\n"; // DateTimeオブジェクトでタイムゾーンを指定しない場合、デフォルトタイムゾーンが使われる $defaultTimeObj = new DateTime('now'); echo "Current time (Default using DateTime): " . $defaultTimeObj->format('Y-m-d H:i:s P') . "\n"; ?> 2025-04-12 スー | PHP Conference Odawara 2025 112

Slide 113

Slide 113 text

このフローを理解することで、PHPアプリケーションで日時を正確に扱うための設定 やコーディングが可能になります。特に、 php.ini での設定漏れによる警告や、意図 しないタイムゾーンでの時刻表示を防ぐことが重要です。 2025-04-12 スー | PHP Conference Odawara 2025 113