まずPeriodクラス,Ymdクラスのコンストラクタに入力チェック?というか整形?用のコードを付け足します。
Periodクラス function __construct($gdate)
$temp = preg_replace("/-+/", "-", $gdate);
$temp = preg_replace("(^-|-$)", "", $temp);
連続する[-]ハイフンを1個にして、行頭または行末のハイフンを削除します。
Ymd(日付抽象)クラス function __construct($date)
$temp = preg_replace("/[^0-9.]/", "", $date);
$temp = preg_replace("/\.+/", ".", $temp);
$temp = preg_replace("/(^\.|\.$)/", "", $temp);
数値と[.]ピリオド以外は削除して、連続ピリオドを1個に、行頭・行末のピリオドを削除します。
次に日付のtoクラスの方ですが、今までのところでは値がセットされていない場合はfromと同じように1を返していましたが、これを次のようなルールで適当な値を返すように書き換えます。
・年の値がない場合は、fromの年
・月の値がない場合は、fromの月があればそれ、なければ12
・日の値がない場合は、fromの日があればそれ、なければ月の最後の日
というようにしたいのですが、いずれにしろtoからfromに問い合わせる必要があるため、まずコンストラクタを書き換えてfromへの参照を保持するようにします。
class dateTo extends Ymd
{
private $from;
function __construct($date, Ymd $from)
{
$this->from = $from;
parent::__construct($date);
}
:
:
}
この変更に伴いPeriodクラスからdateToを生成している部分を書き換えます。
$this->from = new dateFrom($from);
$this->to = new dateTo($to, $this->from);
先にfromのインスタンスを生成して、toを生成するときにはそれを渡します。
尚、前回は端折っていましたが、Ymdクラス(dateFromとdateToの親)でメンバを初期化するinit()を定義し、それぞれの子クラスで実装します。
abstract class Ymd
{
protected $year;
protected $month;
protected $day;
function __construct($date)
{
$temp = preg_replace("/[^0-9.]/", "", $date);
$temp = preg_replace("/\.+/", ".", $temp);
$temp = preg_replace("/(^\.|\.$)/", "", $temp);
$temp = explode('.', $temp, 3);
:
:
$this->init($tempDate);
}
abstract function init(array $date);
:
:
}
dateFromクラス
function init(array $date)
{
list($this->year, $this->month, $this->day) = $date;
}
dateToクラス
function init(array $date)
{
switch (count($date))
{
case 1:
$this->day = $date[0];
break;
case 2:
if ($date[0] <= 1900)
{
list($this->month, $this->day) = $date;
} else {
list($this->year, $this->month) = $date;
}
break;
case 3:
list($this->year, $this->month, $this->day) = $date;
break;
}
}
dateFromの方は単純に配列をlist()でセットしているだけです。この場合値の数が足りない場合は単にセットされないだけです。つまり年月日の順で値がセットされていくということです。
dateToの方はdateFromとはほぼ逆で、値が1個の時はそれを「日」とみなします。値が3個全部揃っている場合はdateFromと同じですが、値が2個の時は1個目の値に閾値を設けて、それより大きな場合は「年月」とし小さい場合は「月日」とみなすことにします。閾値はとりあえず適当に1900としました。
そしてdateToの年月日それぞれのゲッターですが、↑のルールに則って次のように書きました。
function getYear()
{
if ($this->year <> '')
{
return $this->year;
} else {
return $this->from->getYear();
}
}
function getMonth()
{
if ($this->month <> '')
{
return $this->month;
} else {
if ($this->from->month <> '')
{
return $this->from->getMonth();
} else {
return 12;
}
}
}
function getDay()
{
if ($this->day <> '')
{
return $this->day;
} else {
if ($this->from->day <> '')
{
return $this->from->getDay();
} else {
return date('t', mktime(0,0,0,$this->getMonth,1,$this->getYear));
}
}
}
で、これでだんだんと希望のものに近づいてはきているのですが、一番の問題はmktime()に依存している部分で、これをどうにかできないか?と考えて…いやPHPのマニュアルを見ていたところ、カレンダー関数なるものを見つけました。
で、UNIXタイムスタンプの縛りがないということが判明。急遽そっちを使うことにしました。
ラベル:codeigniter PHP