リクエスト詳細
🐛 バグ報告
対応完了
対象アプリ: 合体ドロップ
月曜日に「今週」ランキングの週開始日がズレて集計漏れが起きる不具合
1. 不具合の内容
lib.php の vd_jst_week_start() が、JST基準で本日が月曜日のときに「来週の月曜日」の日付を返してしまい、「今週」ランキング(rank_check.php の weekly、rank_export.php の weekly、ranking画面の今週タブ)の集計期間が壊れる。
2. 根拠・発生しそうな条件
lib.php の該当コード:
```php
function vd_jst_week_start(): string {
$tz = new DateTimeZone('Asia/Tokyo');
return (new DateTimeImmutable('now', $tz))->modify('monday this week')->format('Y-m-d');
}
```
PHPのDateTime相対フォーマット文字列には広く知られた仕様上の癖があり、現在日がすでに指定曜日(この場合Monday)と一致する場合、'monday this week' は「今日」ではなく「翌週の月曜日」を返す(例: 2024-01-01が月曜日のとき、(new DateTime('2024-01-01'))->modify('monday this week') は 2024-01-08 になる)。
この関数の戻り値は rank_check.php の weekly集計や rank_export.php の weekly CSV、ranking.php の今週タブで `WHERE score_date BETWEEN week_start AND today` のように使われている。月曜日にアクセスすると week_start(翌週月曜) > today(当日) となり、MySQLのBETWEENは start > end の場合0件になるため、毎週月曜日は「今週」ランキングが常に0件表示・0位表示になる。日替わりランキングや歴代ランキングには影響しないため気づきにくいが、週次データを扱うすべての画面・API(タイトル、ランキング画面、順位プレビュー、CSV出力)に共通して影響する。
3. 期待動作
本日が月曜日であっても、vd_jst_week_start() はその日自身(今日の日付)を週の開始日として返し、「今週」ランキングに本日を含む当該週のスコアが正しく表示されること。
4. 修正方針
vd_jst_week_start() を自然言語の相対フォーマットに依存しない実装に変更する。例:
```php
function vd_jst_week_start(): string {
$tz = new DateTimeZone('Asia/Tokyo');
$now = new DateTimeImmutable('now', $tz);
$dow = (int)$now->format('N'); // 1=Mon ... 7=Sun
return $now->modify('-' . ($dow - 1) . ' days')->format('Y-m-d');
}
```
これにより月曜日は当日そのもの、火〜日曜日はそれぞれ直近の月曜日を正しく返すようになる。他のweekly関連コード(rank_check.php, rank_export.php, ranking.php, vd_weekly_top_scores)はこの関数の戻り値をそのまま使っているため、修正はこの1関数のみで完結し、既存のAPI・DBスキーマ・呼び出し側コードへの変更は不要。
lib.php の vd_jst_week_start() が、JST基準で本日が月曜日のときに「来週の月曜日」の日付を返してしまい、「今週」ランキング(rank_check.php の weekly、rank_export.php の weekly、ranking画面の今週タブ)の集計期間が壊れる。
2. 根拠・発生しそうな条件
lib.php の該当コード:
```php
function vd_jst_week_start(): string {
$tz = new DateTimeZone('Asia/Tokyo');
return (new DateTimeImmutable('now', $tz))->modify('monday this week')->format('Y-m-d');
}
```
PHPのDateTime相対フォーマット文字列には広く知られた仕様上の癖があり、現在日がすでに指定曜日(この場合Monday)と一致する場合、'monday this week' は「今日」ではなく「翌週の月曜日」を返す(例: 2024-01-01が月曜日のとき、(new DateTime('2024-01-01'))->modify('monday this week') は 2024-01-08 になる)。
この関数の戻り値は rank_check.php の weekly集計や rank_export.php の weekly CSV、ranking.php の今週タブで `WHERE score_date BETWEEN week_start AND today` のように使われている。月曜日にアクセスすると week_start(翌週月曜) > today(当日) となり、MySQLのBETWEENは start > end の場合0件になるため、毎週月曜日は「今週」ランキングが常に0件表示・0位表示になる。日替わりランキングや歴代ランキングには影響しないため気づきにくいが、週次データを扱うすべての画面・API(タイトル、ランキング画面、順位プレビュー、CSV出力)に共通して影響する。
3. 期待動作
本日が月曜日であっても、vd_jst_week_start() はその日自身(今日の日付)を週の開始日として返し、「今週」ランキングに本日を含む当該週のスコアが正しく表示されること。
4. 修正方針
vd_jst_week_start() を自然言語の相対フォーマットに依存しない実装に変更する。例:
```php
function vd_jst_week_start(): string {
$tz = new DateTimeZone('Asia/Tokyo');
$now = new DateTimeImmutable('now', $tz);
$dow = (int)$now->format('N'); // 1=Mon ... 7=Sun
return $now->modify('-' . ($dow - 1) . ' days')->format('Y-m-d');
}
```
これにより月曜日は当日そのもの、火〜日曜日はそれぞれ直近の月曜日を正しく返すようになる。他のweekly関連コード(rank_check.php, rank_export.php, ranking.php, vd_weekly_top_scores)はこの関数の戻り値をそのまま使っているため、修正はこの1関数のみで完結し、既存のAPI・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