カウントダウンタイマーがスマートフォンで正しく表示されない問題について、その原因と解決策をブログ形式でまとめました。この問題は、日付フォーマットの互換性が主な原因です。特にJavaScriptのDate
コンストラクタがスマートフォンのブラウザで意図した通りに動作しない場合に発生します。
Table of Contents
背景
今回オンラインでガチャをを引くためのシステムをRailsで開発する過程で、ガチャの公開までのカウントダウンがスマートフォンで表示されないことがわかった為、その原因と解決策をこのブログに残そうと思いました。
では、早速本題に入っていきます。
原因: 日付フォーマットの互換性
JavaScriptのDate
コンストラクタは、日付文字列を解析してDateオブジェクトを生成します。しかし、このコンストラクタがサポートするフォーマットがブラウザやデバイスによって異なるため、以下のような状況が発生します:
- デスクトップブラウザ
比較的柔軟に日付フォーマットを解釈します(例:YYYY-MM-DD HH:mm:ss
)。 - スマートフォンブラウザ
より厳密なフォーマット、特にISO 8601形式(例:YYYY-MM-DDTHH:mm:ssZ
)を要求する場合が多いです。これ以外の形式ではInvalid Date
エラーが発生することがあります。
問題の例
以下の例を使って、正しく動作しないフォーマットと動作するフォーマットを比較します。
① 問題のあるフォーマット
<div data-start-at="2025-01-24 10:00:00" data-end-at="2025-01-25 10:00:00"></div>
- この形式(
YYYY-MM-DD HH:mm:ss
)はデスクトップブラウザでは解釈されることが多いですが、スマートフォンブラウザではエラーになります。 - 理由: ISO 8601準拠ではなく、ブラウザ間で解釈が異なる可能性があるため。
② 正しいフォーマット
<div data-start-at="2025-01-24T10:00:00Z" data-end-at="2025-01-25T10:00:00Z"></div>
- この形式はISO 8601形式で、すべてのブラウザで一貫して解釈されます。
T
: 日付と時間の区切り文字。Z
: UTC(協定世界時)を表します。
Railsでの解決策: ISO 8601形式を使用
※問題のコード
<div id="countdown-<%= gacha.id %>"
class="countdown-timer"
data-start-at="<%= gacha.start_at %>"
data-end- at="<%= gacha.end_at %>">
<h5><%= t("homes.gacha.before_released_time") %></h5>
<h1></h1>
</div>
データ属性にISO 8601形式の日付を指定するようにコードを修正します。
修正後の例
以下のように、Railsアプリケーションではutc
とiso8601
を使用して正しいフォーマットで出力します。
<div id="countdown-<%= gacha.id %>"
class="countdown-timer"
data-start-at="<%= gacha.start_at.utc.iso8601 %>"
data-end-at="<%= gacha.end_at.utc.iso8601 %>">
<h5><%= t("homes.gacha.before_released_time") %></h5>
<h1></h1>
</div>
utc
: 日時をUTCに変換し、タイムゾーンのずれを防止。iso8601
: ISO 8601形式で日時を出力。
これでスマートフォンでもカウントダウンが表示されるようになりました。
なぜISO 8601形式が必要なのか?
ISO 8601形式は、日時を標準化するフォーマットであり、以下のメリットがあります
- 互換性の向上: すべての主要なブラウザで解釈が統一される。
- タイムゾーンの明確化:
Z
またはタイムゾーンオフセットでタイムゾーンを指定できる。 - 信頼性の向上: フォーマットエラーを防ぎ、コードの堅牢性が向上する。
まとめ
スマートフォンでカウントダウンが表示されなかった原因は、data-start-at
とdata-end-at
に設定した日付フォーマットがブラウザで解釈されなかったためです。これを解決するには、ISO 8601形式を使用することでブラウザ間の互換性を確保し複数のブラウザで表示されるようにしましょう。
適切なフォーマットで修正すれば、すべてのデバイスで正常にカウントダウンタイマーが動作するはずです。今後、日付データを扱う際は標準フォーマットを使用することをおすすめします。
【その他社内ブログ】
・Ruby on Railsでlink_toを別タブで表示する方法
・正常系テストと異常系テストの違い、必要性について解説【初心者】
・Rails開発におけるN+1問題への対策と解決方法