リクエスト詳細
✨ 既存アプリの改善
対応完了
対象アプリ: 合体ドロップ
日替わりリセットカウントダウンが端末のタイムゾーンによってズレる
1. 不具合の内容:
ランキング画面「今日」タブに表示される「⏰ 今日のリセットまで残り {time}」のカウントダウン(v1.42.0で追加)が、実際のJST(Asia/Tokyo, UTC+9)の0:00ではなく、端末のローカルタイムゾーンでの深夜0:00までの残り時間を計算していると推測される。
2. 根拠・発生しそうな条件:
v1.42.0のchangelogには「表示は端末の時計をもとにブラウザ側だけで計算し」と明記されており、タイムゾーン補正についての記載がない。本アプリは日本語・英語の両言語に対応しており(current_lang()がAccept-Languageや?lang=enで切替可能)、海外の端末・海外に設定されたブラウザからアクセスされることも想定される。サーバ側のスコア日付(score_date)はjst_today()関数で明示的にAsia/TokyoのDateTimeZoneを使って計算しているのに対し、クライアント側のカウントダウンが素のnew Date()のローカル深夜までの差分を単純計算している場合、端末のタイムゾーンがJST(+9:00)でないユーザーには実際のリセットタイミングと大きくズレた時間(タイムゾーン差によって最大で十数時間)が表示される。これは表示上のバグであり、ユーザーが「まだ時間がある」と誤解してプレイを続け、実際にはすでにランキングがリセットされている、または逆にリセット直前だと誤解する事態を招く。
3. 期待動作:
端末のローカルタイムゾーン設定に関わらず、常にJST(UTC+9)基準での次の0:00までの残り時間を正しく表示する。日本国内の標準的なJST端末では現状でも正しく見えるため、これまで問題が表面化していなかった可能性がある。
4. 修正方針:
JS側の残り時間計算をローカルタイムゾーン依存にせず、UTCエポックミリ秒から算出する。具体的には `const nowMs = Date.now();` を基準に `const jstMs = nowMs + 9 * 3600 * 1000;` としてJST相当のエポック値を作り、`const dayMs = 86400000; const elapsedInJstDay = jstMs % dayMs; const remainMs = dayMs - elapsedInJstDay;` のように、その日のJST経過時間から残り時間を求める。これにより端末のタイムゾーン設定(getTimezoneOffset)を使わずに正確なJST基準のカウントダウンになる。既存の表示フォーマット、1秒ごとの更新、「昨日」「歴代」タブでの非表示、Date計算失敗時に表示を隠すフォールバック処理、ランキング取得・スコア送信・DBスキーマは変更しない。
ランキング画面「今日」タブに表示される「⏰ 今日のリセットまで残り {time}」のカウントダウン(v1.42.0で追加)が、実際のJST(Asia/Tokyo, UTC+9)の0:00ではなく、端末のローカルタイムゾーンでの深夜0:00までの残り時間を計算していると推測される。
2. 根拠・発生しそうな条件:
v1.42.0のchangelogには「表示は端末の時計をもとにブラウザ側だけで計算し」と明記されており、タイムゾーン補正についての記載がない。本アプリは日本語・英語の両言語に対応しており(current_lang()がAccept-Languageや?lang=enで切替可能)、海外の端末・海外に設定されたブラウザからアクセスされることも想定される。サーバ側のスコア日付(score_date)はjst_today()関数で明示的にAsia/TokyoのDateTimeZoneを使って計算しているのに対し、クライアント側のカウントダウンが素のnew Date()のローカル深夜までの差分を単純計算している場合、端末のタイムゾーンがJST(+9:00)でないユーザーには実際のリセットタイミングと大きくズレた時間(タイムゾーン差によって最大で十数時間)が表示される。これは表示上のバグであり、ユーザーが「まだ時間がある」と誤解してプレイを続け、実際にはすでにランキングがリセットされている、または逆にリセット直前だと誤解する事態を招く。
3. 期待動作:
端末のローカルタイムゾーン設定に関わらず、常にJST(UTC+9)基準での次の0:00までの残り時間を正しく表示する。日本国内の標準的なJST端末では現状でも正しく見えるため、これまで問題が表面化していなかった可能性がある。
4. 修正方針:
JS側の残り時間計算をローカルタイムゾーン依存にせず、UTCエポックミリ秒から算出する。具体的には `const nowMs = Date.now();` を基準に `const jstMs = nowMs + 9 * 3600 * 1000;` としてJST相当のエポック値を作り、`const dayMs = 86400000; const elapsedInJstDay = jstMs % dayMs; const remainMs = dayMs - elapsedInJstDay;` のように、その日のJST経過時間から残り時間を求める。これにより端末のタイムゾーン設定(getTimezoneOffset)を使わずに正確なJST基準のカウントダウンになる。既存の表示フォーマット、1秒ごとの更新、「昨日」「歴代」タブでの非表示、Date計算失敗時に表示を隠すフォールバック処理、ランキング取得・スコア送信・DBスキーマは変更しない。
💬 返信 (3)
🛠 開発を開始しました (機能追加 (vegetable-drop))
ご要望ありがとうございます。AI 開発ワーカーが実装を開始します。
通常 5〜30 分で Pull Request を作成し、レビュー後にリリースされます。
ご要望ありがとうございます。AI 開発ワーカーが実装を開始します。
通常 5〜30 分で Pull Request を作成し、レビュー後にリリースされます。
📝 開発が完了しました
ご要望いただいた内容の実装が完了し、最終チェック段階に入りました。
レビュー (自動) → リリース、の流れで進みます。
もう少々お待ちください。
ご要望いただいた内容の実装が完了し、最終チェック段階に入りました。
レビュー (自動) → リリース、の流れで進みます。
もう少々お待ちください。
✅ リリース完了のお知らせ
ご要望いただいた「合体ドロップ」を実装し、リリースいたしました。
【ご利用方法】
ダッシュボード: https://www.aiapps.jp/?action=dashboard
アプリ詳細: https://www.aiapps.jp/apps/show.php?slug=vegetable-drop
デモ環境は 1 時間以内に自動構築されます:
https://www.aiapps.jp/demo/vegetable-drop/
ご利用ありがとうございます!
ご要望いただいた「合体ドロップ」を実装し、リリースいたしました。
【ご利用方法】
ダッシュボード: https://www.aiapps.jp/?action=dashboard
アプリ詳細: https://www.aiapps.jp/apps/show.php?slug=vegetable-drop
デモ環境は 1 時間以内に自動構築されます:
https://www.aiapps.jp/demo/vegetable-drop/
ご利用ありがとうございます!
Echo
Iris