ごもちゃ箱BLOG

自作の PHP クラスライブラリ PEACH の開発日記です。

PHPで ISO8601 形式の時刻のバリデーション

以下の記事に触発されて, 拙作のライブラリを利用して ISO8601 形式の時刻 (正確には W3CDTF になりますが) のバリデーション関数を作ってみました. sota1235.hatenablog.com

下準備として Composer で PEACH2 ライブラリを準備します.

$ composer require trashtoy/peach2

以下がコード本体です.

<?php

use Peach\DT\W3cDatetimeFormat;
use Peach\DT\Timestamp;

require_once(__DIR__ . "/vendor/autoload.php");

$validateDate = function ($str) {
    try {
        // +09:00 を前提 (固定) として, 書式オブジェクト $f を作成します
        $f     = new W3cDatetimeFormat(-540); 
        // $f を使用して 文字列を Timestamp オブジェクトに変換します
        $t     = Timestamp::parse($str, $f);
        // $f を使用して Timestamp オブジェクトを文字列に再変換します
        $str2  = $t->format($f);
        // 元の文字列と再変換した文字列が同一であればバリデーション OK
        return ($str === $str2);
    } catch (InvalidArgumentException $e) {
        // parse に失敗した場合は NG
        return false;
    }
};

$testCases = [
    // 日付のみ指定のケース
    '2016-09-30',
    // 日付と時刻の間のTが抜けてるケース
    '2016-09-01 12:00:00+09:00',
    // タイムゾーンが抜けてるケース
    '2016-09-30T12:00:00',
    // 日付がでたらめなケース
    '2016-15-01T12:00:00+09:00', // 月
    '2016-09-31T12:00:00+09:00', // 日
    '2016-09-01T25:00:00+09:00', // 時
    '2016-09-01T12:61:00+09:00', // 分
    '2016-09-01T12:00:61+09:00', // 秒
    '2016-09-31T12:00:00+09:00', // 存在しない31日
    '2016-12-26T18:59:59+09:00', // OK
];

print_r(array_map($validateDate, $testCases));

以下が出力となります. 各テストケースを $validateDate に通した結果, 最後の文字列だけ true になりました.

Array
(
    [0] =>
    [1] =>
    [2] =>
    [3] =>
    [4] =>
    [5] =>
    [6] =>
    [7] =>
    [8] =>
    [9] => 1
)

タイムゾーンをハードコーディングで固定しているところがちょっとイケてないですね. (ちょっといじれば改善できそうですが)

今回のコードで使用されたクラスの API はこちらです.

PEACH2 の大型アップデートの準備中

オレオレフレームワークの実装の準備段階として, HTTP リクエスト・レスポンスの処理に焦点を置いた Http モジュールを公開する予定です.

Markup モジュールの API にも大きく手が加わります. (つまり後方互換性を失います. 現状で使っている人皆無なのでいいよね)

汎用PHPクラスライブラリ PEACH のバージョン 1.1.0 をリリースしました

PHP 7.0 がリリースされた今日この頃ですが, 惰性で PHP 5.1+ のサポートを続けております.

今回リリースした 1.1.0 の主な変更内容は, 8月にリリースしたバージョン 2.1.0 のバックポートです. 具体的にはデータ変換用のモジュール DF が追加されました. 例えば任意のオブジェクトを JSON 文字列に変換したり, その逆をやったり, といったことができます.

詳しい使い方は以下のドキュメントをご覧ください.

データ変換モジュール DF

汎用PHPクラスライブラリ PEACH の ver 2.0.1 をとっくにリリースしてました

例によって公開してだいぶ後になってからの報告になりますが, 自作 PHP クラスライブラリの新しいバージョンをリリースしました.

ダウンロードはコチラから. Releases · trashtoy/PEACH2 · GitHub

内容は細かいブラッシュアップ (単体テストのコードカバレッジ率を 100% 近くまで引き上げ, その過程で見つかった細かいバグを解消したり) や PHPDoc コメントの充実が中心なのですが, 1 点新しく追加された API に, 日本語の曜日文字列のサポートというものがあります. 詳しい内容は Qiita のほうに書きましたのでそちらをご覧ください.

[PHP5.3+] PHPで曜日文字列を含む日付・時刻の書式を扱うAPI - Qiita

ドキュメント書くの超疲れる。。。だるい。。。orz

でもちゃんと書かないと使ってくれる人が現れないだろうし未来の自分もきっと困ると思うので, しっかり向き合わないと.

汎用PHPクラスライブラリ PEACH の ver 2.0.0 がリリースされてました

今更ながら報告ですが, さる 2014/12/08 に PEACH のバージョン 2 をリリースしました.
ようやくクラス名の namespace 対応が出来ましたー. もう PHP 5.6 もとっくに出て PHP 5.3 系の開発もストップしたというのにこのgdgdなスピード感よ.

まだドキュメンテーションが全然追い付いていないのですが, とりいそぎ Qiitaチュートリアル記事をいろいろ載せていこうと思っています.

今まで出した記事一覧:

汎用PHPクラスライブラリ PEACH の ver 1.0.1 をリリースしました

PHP クラスライブラリ PEACH のマイナーバージョンアップを行いました.
ver 2.0.0 の公開に向けた細かいバグフィックスリファクタリングが中心となります.

ドキュメント
PEACH
ソースコードのダウンロード (ZIP)
https://github.com/trashtoy/PEACH/archive/1.0.1.zip


今回からドキュメンテーションを submodule 化してみました. プロジェクト全体におけるドキュメントの比重がかなり大きかったので, phpDocumentor でドキュメント一式を再生成するたびに大掛かりな更新が発生してしまうのを避けるためです.
あと, ソースコードだけ欲しい (ドキュメントはオンラインから確認できれば良い) というユーザーの負担を減らすという目的もあります.

手元にドキュメントを置きたい場合は以下のコマンドを実行すれば OK です.

$ git clone git@github.com:trashtoy/PEACH.git /path/to/peach
$ cd /path/to/peach
$ git submodule init
$ git submodule update

DT の扱い方 (第 2 回)

今回は, 自作の汎用 PHP クラスライブラリ "PEACH" の解説として, 前回に引き続き DT (Date and Time) モジュールの tips を紹介していきます. 今回は主に文字列処理について.

(PEACH ライブラリに関する詳細はこちら: http://trashtoy.github.io/peach/ )

基本

format() メソッドで時間オブジェクトを "YYYY-MM-DD", "YYYY-MM-DD hh:mm", "YYYY-MM-DD hh:mm:ss" 形式の文字列に変換することができます.

<?php
require_once("/path/to/PEACH2/src/autoload.php");
use Peach\DT\Date;
use Peach\DT\Datetime;
use Peach\DT\Timestamp;

$t1 = Date::now();
$t2 = Datetime::now();
$t3 = Timestamp::now();
var_dump($t1->format());
var_dump($t2->format());
var_dump($t3->format());

出力

string(10) "2014-08-25"
string(16) "2014-08-25 22:15"
string(19) "2014-08-25 22:15:07"

parse() メソッドは文字列を時間オブジェクトに変換することができます. (format と逆の操作です)

<?php
require_once("/path/to/PEACH2/src/autoload.php");
use Peach\DT\Date;

$t = Date::parse("2012-05-21");
var_dump($t->get("year"));
var_dump($t->get("month"));
var_dump($t->get("date"));

出力

int(2012)
int(5)
int(21)

書式を定義して入出力

JavaSimpleDateFormat (Java Platform SE 8) みたいな感じで, ユーザー定義の書式を入出力をすることができます.

文字列に変換する場合は以下のようなコードになります. format() の引数に SimpleFormat オブジェクトを指定します.

<?php
require_once("/path/to/PEACH2/src/autoload.php");
use Peach\DT\Timestamp;
use Peach\DT\SimpleFormat;

$f = new SimpleFormat("Y年n月j日 H:i:s");
$t = Timestamp::now();
var_dump($t->format($f));

出力

string(25) "2014年8月25日 22:15:07"

文字列を時間オブジェクトに変換する場合はこんな感じです. parse() の第 2 引数に SimpleFormat オブジェクトを指定します.

<?php
require_once("/path/to/PEACH2/src/autoload.php");
use Peach\DT\Timestamp;
use Peach\DT\SimpleFormat;

$f = new SimpleFormat("Y年n月j日 H:i:s");
$t = Timestamp::parse("2012年5月12日 07:34:56", $f);
var_dump($t->get("year"));
var_dump($t->get("month"));
var_dump($t->get("date"));
var_dump($t->get("hour"));
var_dump($t->get("minute"));
var_dump($t->get("second"));

出力

int(2012)
int(5)
int(12)
int(7)
int(34)
int(56)

パターン文字列には以下の種類があります. (SimpleFormat の API にも同じ情報を記載しています)

Y
年 (4桁固定, 例: "2014")
m
月 (2桁固定, 例: "05")
n
月 (1~2桁, 例: "5")
d
日 (2桁固定, 例: "01")
j
日 (1~2桁, 例: "1")
H
時 (2桁固定, 例: "07")
G
時 (1~2桁, 例: "7")
i
分 (2桁固定, 例: "02")
f
分 (1~2桁, 例: "2")
s
秒 (2桁固定, 例: "00")
b
秒 (1~2桁, 例: "0")

今日はここまで. 今回挙げた SimpleFormat 以外にも様々な Format クラスが存在するので, 次回はそちらも紹介していこうと思います.