【個人開発】1か月後を足したら「2月31日」ができた|サブスクの更新日がずれていくバグと直し方

1か月後を足したら2月31日ができた サブスクの更新日がずれていくバグと直し方

※このサイトの記事内では広告を掲載している場合があります。

毎月31日に更新するサブスクの「次の更新日」を計算したら、2月31日という存在しない日ができてしまい、更新日が少しずつずれていく。自作アプリ「サブスク番人」を作っているときに、このバグを踏みました。

この記事では、何が起きたのか、なぜずれるのか、今どう直しているのかをまとめます。日付の計算をするアプリを作る人の参考になればうれしいです。

同じ話は、30秒ほどのショート動画でも紹介しています。

何が起きたか

「サブスク番人」は、サブスクの更新日の前に知らせてくれるアプリです。更新日を知らせるには、今の更新日から「次の更新日」を計算する必要があります。

毎月払いなら、次の更新日は「1か月後」。ここで、毎月31日に更新するサブスクに1か月を足すと、2月31日のような存在しない日になってしまいました。その結果、更新日が少しずつずれていくバグになっていました。

なぜずれるのか

「1か月後」は、月によって日数がちがう(28日〜31日)ので、思ったよりあいまいです。ここからは、アプリの中の話ではなく、日付を計算するときに一般的に起きることです。

毎月31日に更新するサブスクの次の更新日を、3つの計算方法で比べた図

A そのまま1か月足すと、はみ出す

たとえば JavaScript の Date で、2026年1月31日の月に1を足すと、2月31日は無いので、はみ出した3日分が3月に回って3月3日になります。そこから先は毎月3日になり、31日には戻りません。

B 月末にそろえても、前回の日から足すと縮んでいく

「その月にない日は月末にそろえる」と、1月31日の次は2月28日になります。ただし、次の計算を前回の更新日(2月28日)からすると、3月28日、4月28日…と、28日のまま進んでしまいます。

C 「31日」を覚えておいて、毎回そこから決める

もとの「31日」を覚えておいて、毎回「その月の31日。なければ月末」と決めると、2月28日、3月31日、4月30日と、月末に合わせて進みます。うるう年の2028年なら、2月は29日になります。

今の直し方

まず、その月にその日がない場合は、月末にそろえるようにしました。1月31日の次は2月28日です。

ただ、最初の直し方では、その次を前回の更新日(2月28日)から計算していたので、3月28日になっていました。上の図でいうとBのやり方です。

そこで、サブスクごとにもとの更新日(31日など)を覚えておき、毎回そこから決めるように直しました(図のC)。1月31日の次は2月28日、その次は3月31日、4月30日と、月末に合わせて進みます。毎年2月29日に更新するものも、うるう年には2月29日に戻ります。この直しは、次のアプリの更新から使えます。

なお、前のバージョンですでに28日にずれてしまったサブスクは、もとが何日だったかの記録がないので、自動では戻りません。編集画面で更新日を選び直すと、その日が新しい基準になります。

日付の計算は、ふだんの日(たとえば15日)では問題が出ません。月末の29日・30日・31日と、うるう年の2月だけで起きるので、気づきにくいバグでした。

日付を計算するアプリを作る人へ

  • 「1か月後」を計算するところでは、1月31日・3月31日・5月31日から始めて、何か月か先まで確かめる
  • うるう年の2月29日と、30日までの月(4月・6月・9月・11月)も確かめる
  • 前回の結果から足していくと、そろえた日がそのまま残る(上の図のB)。もとの日を覚えておくかどうかを決めておく

まとめ

  • 毎月31日のサブスクに1か月足したら、2月31日という存在しない日ができた
  • そのせいで、更新日が少しずつずれていくバグになっていた
  • 月末にそろえるだけだと、そのあと28日のまま進んでいた
  • 今は、もとの日を覚えておいて毎回そこから決める(1月31日 → 2月28日 → 3月31日)

「サブスク番人」は、App Store と Google Play で「サブスク番人」と検索すると見つかります。アプリを作って公開するまでの話は、「サブスク番人」を作って公開した話にまとめています。

ほかに作ったアプリは 作ったもの にまとめています。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

CAPTCHA