[PHP5.3+] PHPで日付・時間操作をカンタンに出来るAPIの紹介

PHP で日付や時刻の計算を行う時, 皆様はどんなやり方をしていますか？
おそらく date(), time(), strtotime() などの関数や DateTime クラスなどで試行錯誤している方が大半なのではと思います.
個人的にもっと直感的でラクに使える日付・時刻操作 API が欲しかったので作りました.
以下, 自作の汎用 PHP クラスライブラリ (PEACH) の紹介です.

**※この記事は PHP5.3.0 以上の環境が対象です. PHP 5.1 系, 5.2 系をお使いの方は [バージョン 1 系の解説記事](http://qiita.com/trashtoy/items/3f9e7c0d4a97fe2eda2b) をご覧ください.**

## 導入

1. https://github.com/trashtoy/PEACH2/archive/2.0.0.zip から最新版 (2.0.0) をダウンロードしましょう. (2014/12/08 現在)
2. ZIP ファイルを展開し, src ディレクトリを適当なディレクトリに配置します.
3. PHP ファイルで以下のように autoload.php を読み込むだけで OK です.

```php
<?php
require_once("/path/to/peach/src/autoload.php");

// Your code here...
```

## 時間オブジェクトの生成

時間オブジェクトには

* Peach\DT\Date (日付)
* Peach\DT\Datetime (日付時刻, 分まで)
* Peach\DT\Timestamp (日付時刻, 秒まで)

の 3 種類があります.

```php
<?php
require_once("/path/to/peach/src/autoload.php");

use Peach\DT\Date;
use Peach\DT\Datetime;
use Peach\DT\Timestamp;

$d1 = new Date(2012, 5, 21);
$d2 = new Datetime(2012, 5, 21, 7, 34);
$d3 = new Timestamp(2012, 5, 21, 7, 34, 45);

var_dump($d1->format()); // string(10) "2012-05-21"
var_dump($d2->format()); // string(16) "2012-05-21 07:34"
var_dump($d3->format()); // string(19) "2012-05-21 07:34:45"
```

今日の日付 (または現在時刻) は now() メソッドで取得します.

```php
require_once("/path/to/peach/src/autoload.php");

use Peach\DT\Date;
use Peach\DT\Datetime;
use Peach\DT\Timestamp;

$d1 = Date::now();
$d2 = Datetime::now();
$d3 = Timestamp::now();

var_dump($d1->format()); // string(10) "2014-12-16"
var_dump($d2->format()); // string(16) "2014-12-16 21:37"
var_dump($d3->format()); // string(19) "2014-12-16 21:37:22"
```

## フィールドの参照

get メソッドの引数に `year`, `month`, `date`, `hour`, `minute`, `second` などの文字列を指定することで, 対応するフィールドを取得することが出来ます.

```php
<?php
require_once("/path/to/peach/src/autoload.php");

use Peach\DT\Date;

$date = new Date(2012, 5, 21);
var_dump($date->get("year"));  // int(2012)
var_dump($date->get("month")); // int(5)
var_dump($date->get("date"));  // int(21)
```

## フィールドの変更

`set`, `add` などのメソッドを使ってフィールドの変更が出来ます.
これらのメソッドは, 自身のフィールドを変更するのではなく, 新しい時間オブジェクトを返します.
PHP 5.5 で導入された [DateTimeImmutable](http://jp.php.net/manual/ja/class.datetimeimmutable.php) クラスの挙動に近いです.

### set メソッド

日付の「月」の値を 5 から 10 に変更します.

```php
<?php
require_once("/path/to/peach/src/autoload.php");

use Peach\DT\Datetime;

$date = new Datetime(2012, 5, 21, 7, 34);
var_dump($date->format()); // string(16) "2012-05-21 07:34"
$test = $date->set("month", 10);
var_dump($test->format()); // string(16) "2012-10-21 07:34"
```

### add メソッド

とある時刻の 100 分後を計算します.

```php
<?php
require_once("/path/to/peach/src/autoload.php");

use Peach\DT\Datetime;

$date = new Datetime(2012, 5, 21, 7, 34);
var_dump($date->format()); // string(16) "2012-05-21 07:34"
$test = $date->add("minute", 100);
var_dump($test->format()); // string(16) "2012-05-21 09:14"
```

### 複雑な操作

メソッドチェーンを使って「今から 1 年後の 1 週間前の正午」を計算します.

```php
<?php
require_once("/path/to/peach/src/autoload.php");

use Peach\DT\Datetime;

$date = Datetime::now();
var_dump($date->format()); // string(16) "2014-12-16 21:37"
$test = $date->add("year", 1)->add("date", -7)->setAll(["hour" => 12, "minute" => 0]);
var_dump($test->format()); // string(16) "2015-12-09 12:00"
```

## 時間オブジェクトと文字列の相互変換

先ほどのコード例にもありましたが, format メソッドを使ってオブジェクトを文字列に変換出来ます.

```php
<?php
require_once("/path/to/peach/src/autoload.php");

use Peach\DT\Date;
use Peach\DT\Datetime;
use Peach\DT\Timestamp;

$d1 = Date::now();
$d2 = Datetime::now();
$d3 = Timestamp::now();

var_dump($d1->format()); // string(10) "2014-12-16"
var_dump($d2->format()); // string(16) "2014-12-16 21:37"
var_dump($d3->format()); // string(19) "2014-12-16 21:37:22"
```

文字列から時間オブジェクトを生成するには parse メソッドを使います.

```php
<?php
require_once("/path/to/peach/src/autoload.php");

use Peach\DT\Date;
use Peach\DT\Datetime;
use Peach\DT\Timestamp;

$d1 = Date::parse("2012-05-21");
$d2 = Datetime::parse("2012-05-21 07:34");
$d3 = Timestamp::parse("2012-05-21 07:34:45");
var_dump($d1->format()); // string(10) "2012-05-21"
var_dump($d2->format()); // string(16) "2012-05-21 07:34"
var_dump($d3->format()); // string(19) "2012-05-21 07:34:45"
```

### ユーザー指定の書式が使えます

Java の SimpleDateFormat クラスのように, ユーザー指定の書式で文字列と時間オブジェクトの変換が出来ます.

```php
<?php
require_once(dirname(__DIR__) . "/dev/PEACH/src/autoload.php");

use Peach\DT\Timestamp;
use Peach\DT\SimpleFormat;

$f    = new SimpleFormat("Y年n月j日 H:i:s");
$date = Timestamp::parse("2012年5月21日 07:34:45", $f); // 第 2 引数にフォーマットを指定する
var_dump($date->format());                              // string(19) "2012-05-21 07:34:45"

$test = $date->set("month", 10)->add("hour", -5);
var_dump($test->format());                              // string(19) "2012-10-21 02:34:45"
var_dump($test->format($f));                            // string(23) "2012年10月21日 02:34:45"
```

### HTTP-Date の入出力も出来ます

HTTP ヘッダーの `Last-Modified` や `If-Modified-Since` などの取り扱いも簡単です.

```php
<?php
require_once(dirname(__DIR__) . "/dev/PEACH/src/autoload.php");

use Peach\DT\HttpDateFormat;
use Peach\DT\Timestamp;

// php.ini で date.timezone = "Asia/Tokyo" がセットされている前提です

$text = "Sun, 20 May 2012 22:34:45 GMT";          // If-Modified-Since や Last-Modified はこのような書式
$f    = new HttpDateFormat();
$date = Timestamp::parse($text, $f);              // 第 2 引数にフォーマットを指定する
var_dump($date->format());                        // string(19) "2012-05-21 07:34:45"
$test = $date->set("month", 10)->add("hour", -5);
var_dump($test->format());                        // string(19) "2012-10-21 02:34:45"
var_dump($test->format($f));                      // string(29) "Sat, 20 Oct 2012 17:34:45 GMT"
```

## 詳細について

バージョン 2 用のドキュメンテーションはまだ整備されていないので, 代わりにバージョン 1 用の URL  http://trashtoy.github.io/peach/li_DT.html をご覧ください.
クラス名に namespace を使っているかの違いがほとんどなので, 適宜クラスを読み替えていただければと思います.