もう今年も開けて18日目ですが、あけましておめでとうございます。
最近あまり更新ができてないのですが、今年はもう少し頑張って更新していけたらなと思いますが…果たしてどれだけ書けるかな…。
ところで、サイドバーの右上、プロフィールが居るところなんですが、いつもこの時期になると、LVの表記がおかしくなるんですよね。
後で直さないとなー。しかしなんでだろうなー。なんて思ってるうちに元に戻ってしまって結局原因の究明もできない状態だったのですがようやく原因が判明したので修正しました。
後半のタイトルも若干関係あります。
レベル表記が狂う原因
そもそもこのレベルが何を指してるのかといいますと、私の年齢でございます。
B.B.Joker という漫画に、こんなネタが有りました。確か3巻。
これからの高齢化社会、年齢を「レベル」で呼べば敬う気持ちも増すと思う。なんとなく。
母「おじいちゃんは今年でレベル85なのよ」
子「うわー!すごいや!!」
で、ブログのデザインを直してる時にこれをふと思い出しまして。
これはやるしかないな、と。
この漫画はいろいろと衝撃的で、高校時代に友だちに借りて授業中にサボって読んだだけなのにもかかわらず今でも忘れられないネタがたくさんあります。
まぁネタ自体はだれでも思いつきそうなバカバカしい物が多かったりするんですが、それを敢えて漫画にしちゃうあたりとか素敵ですよね。いい加減ちゃんと揃えて買うべきなのだろうか。
さて、話がそれてしまいましたが、要は現在の日付をもとに、誕生日までの残り日数を計算して100%に向かっていき、誕生日を迎えるとレベルが1上がって%は0に戻る、という感じのことをしていたんですね。
で、これ自体は別におかしなことはしていんですが、特定の条件がそろうと表示が壊れます。で、なんでそんなことが起こっていたのかというと、一言で言えばツメが甘かったんですね。
つまり、次の誕生日を求める際に、単純に
1 |
$nextBirthday = new DateTime(date('Y',strtotime('+1 year')).date('m/d',$birthday).'00:00:00'); |
という感じで、単純に「現在の年」に1年足した年の、誕生日になる日付の DateTime オブジェクトを作ってただけなんですね。
で、この方法がどうして問題なのかというと、次の誕生日が「今年」の、まだ未来の日付の場合に、プラス1年されて「今年の誕生日が消滅する」という現象が発生してしまうんですね。
簡単にまとめると、
誕生日が 2/28 日で、今日が 1/18 の場合、 | |
2015/12 | 2016/01 |
(今年) 2015 + 1 で、 この時点での次の誕生日は 2016/02/28 |
(今年)2016 + 1 で、 この時点での次の誕生日は 2017/02/28 |
ということになります。
これを回避するためには、「年開け 1/1 から誕生日までの期間は、次の誕生日を求める際に年をプラス1しない」という条件分岐が必要になってきます。
そしてそのためには、日付比較を行って、今日がその範囲内に居るかどうかを調べる必要があります。
PHPで日付比較
なんかいろいろなやり方があるらしいのですが、一番簡単なのは文字列のママ比較しちゃうことみたいです。(【PHP】日付比較 – Qiitaのコメントより)
なので、今回はこんな感じ
1 2 3 4 5 6 7 8 9 10 |
$today = (isset($debug_date)) ? $debug_date : date('Y/m/d'); $chk_start = date('Y/01/01'); $chk_end = date('Y/'.date('m/d',$birthday)); if ($today >= $chk_start && $today < $chk_end) { $lv = $now_y - $birth_year - 1; $nextBirthday = new DateTime (date('Y').'/'.date('m/d',$birthday) .' 00:00:00'); } else { $lv = $now_y - $birth_year; $nextBirthday = new DateTime (date('Y',strtotime('+1 year')).'/'.date('m/d',$birthday) .' 00:00:00'); } |
1行目は、デバッグの際に任意の日付を $debug_date にいれて試せるようにしてるだけなので、不要なら $today = date('Y/m/d'); でも構いません。
これで計算ズレは解消です。
おまけ
ついでなので %部分の計算方法も載せておきます。他の仕事とかでいつか使うかもしれないしw
次の誕生日についてはもう求まってますので、あとは今日の DateTime オブジェクトを作ってあげれば、
1 2 3 |
$current = new DateTime('now'); $diff = $current->diff($nextBirthday); echo $diff->days; |
みたいな感じで、今日から次の誕生日までの日数が求まります。これには DateTime::diff を使うと便利です。
で、次の誕生日までの残り日数が分かれば、
経過(%)= 100 – ((残り日数 / 1年の日数) * 100)
って感じで求めることができます。PHPコードだとこんな感じ。
1 2 |
$year_days = (date('L') == 0) ? 365 : 366; $percentage = 100 - (round($diff->days / $year_days,3) * 100); |
1年の日数については、 date(‘L’) でうるう年かどうかがわかるので、その判定結果をもとに決めています。因みに date(‘L’) の戻りが 1 ならうるう年、0 ならそれ以外です。
今年はちょうどうるう年なんで1が戻りますね。4年に1回しか見れないんでためしてみると良いですよ(w
コメントする