[Bug] [AS3] Date.time を int に入れちゃってオーバーフロー

Posted: 2014-08-25
Category: BugPattern
Tags: #AS3

概要

いわゆるイベントなど現実時間に連動するサービスのあるゲームを作っているときに、 Client でも端末時間を使って軽くチェックしておく、ということは割とやる。 判定用にこんな関数を書くだろう。

/** まだ終了時刻に達していなかったら true を返す */
public function isOngoingJustNow(endDate:Date):Boolean {
    var endAt:int = endDate.time;
    var now:int   = (new Date()).time;
    return (now <= endAt);
}

一見問題がなさそうだったが、ある特定の終了時刻を設定した場合に、 まだ終了時刻に達していないのに false が返った。

原因

Date.time は経過 ミリ秒 であり、Number 型だ。従って int や uint に入れると溢れる。 UNIXTIME だから秒だろう、と思いがちなので注意。

例えばこのケースだと

  • 2014-09-17 04:45 頃
  • 2014-11-05 21:48 頃

などのタイミングで値が溢れてマイナスに入るため、現在時刻も溢れるタイミングまで来ないと 終了時刻が未来にあっても false を返すようになる。 (溢れるタイミングは 50 日くらいのサイクルで来る)

解決法

Date.time は Number で受け取りましょう。

var now:Number = (new Date()).time;