Zend_Date
の API はシンプルで統一性がありますが、
非常に柔軟で強力な設計になっており、
さまざまな操作や演算ができます。
いくつかのメソッドでは、PHP の date()
関数と似た形式の日付書式文字列を使用します。
PHP の日付書式指定子のほうが ISO 書式指定子よりなじみがあるという場合は、
Zend_Date::setOptions(array('format_type' => 'php'))
とすることができます。こうすると、$format
パラメータを持つすべての関数で PHP の日付書式指定子が使用できるようになります。
Zend_Date::setOptions(array('format_type' => 'iso'))
とすると、デフォルトのモードに戻ります。このモードは、
ISO 日付書式トークンのみをサポートするものです。
サポートする書式コードの一覧は、
項8.5.4. 「PHP の date() 関数の書式指定子を使用して自分で定義する出力フォーマット」 を参照ください。
日付を処理する際には、夏時間の適用前後をまたがってしまうこともあります。
通常は、そのような場合は結果が一時間増えたり減ったりします。
たとえば、夏時間の適用前の日付に何ヶ月か追加してその結果が夏時間適用後になった場合、
結果の日付は一時間ずれます。月末や月初の深夜 0 時のような境界上で、
それをまたがった月の加算を行うと、結果から 1 時間引かれることで
前月末日の日付になってしまい "off by 1" エラーが発生します。
このような状況になることを避けるためには、夏時間の変更を無視するためのオプション
fix_dst
を使用します。夏時間/冬時間の境界をまたぐ際に、
通常は 1 時間分足したり引いたりします。
たとえば、春の夏時間適用日をまたがる日付計算の結果は、
時刻部分が 00:00:00 のままの場合は予期したものより 1 日少なくなります。というのも、
Zend_Date は日付部分ではなくタイムスタンプに基づいて計算を行うからです。
タイムスタンプが 1 時間少なくなるので、日付も予期したものより 1 日少なくなってしまいます。
これを避けるためにはオプション fix_dst
を使用します。
このオプションのデフォルトは true で、この場合は夏時間が
"月" の計算 (addMOnth()、subMonth()
) に影響を与えなくなります。
Zend_Date::setOptions(array('fix_dst' => false))
とすると、
夏時間にあわせた時間の加減算を "月" の計算時にも適用します。
ある日付に対して月を足したり引いたりすると、
もとの日付が月の最後のほうだった場合に予期せぬ結果となることがあります。
たとえば「1月31日」に一ヶ月足すことを考えてみましょう。
SQL に慣れている人なら、この結果は「2月28日」になるものと思われるでしょう。
一方、Excel や OpenOffice を使っている人は、この結果が「3月3日」
になるものと考えるのではないでしょうか。
この問題は、計算結果の月の日数が元の日付の月の日数より少ない場合に起こりえます。
ZF の開発者向けには、どちらの方式かを選択できるようにしました。
extend_month
オプションを false にすると
SQL 風の挙動になり、true にすると表計算ソフト風の挙動になります。
extend_month
のデフォルトは false なので、
Zend_Date
は SQL 互換の計算をします。
デフォルトでは、Zend_Date
は月の計算をする際に
(必要に応じて) 日を切り詰めます。計算した結果に該当する日がその月に存在しなかった場合に、
翌月にまたがることはありません。
Zend_Date::setOptions(array('extend_month' => true));
とすると、表計算ソフトと同様の方式で計算することになります。
Zend_Date
オブジェクトの作成によって入力が正規化されると、
このオブジェクトはタイムゾーンに関連付けられます。しかし、内部的な形式としては通常の
UNIX タイムスタンプを使用します。
各地域固有の方式で日付を表示するには、まずタイムゾーンを知る必要があります。
デフォルトのタイムゾーンは常に GMT/UTC です。オブジェクトのタイムゾーンを調べるには
getTimeZone())
を使用します。オブジェクトのタイムゾーンを変更するには
setTimeZone())
を使用します。
これらのオブジェクトに対するすべての操作は、このタイムゾーンを想定して行われます。
異なるタイムゾーンの日付オブジェクトを混在させないよう注意しましょう。
タイムスタンプにのみかかわる操作しかしないのならよいのですが、
それ以外の場合には期待通りの結果が得られなくなるでしょう。
異なるタイムゾーンの Zend_Date
に対する操作は、
たいていの場合はうまく動作します。というのも Zend_Date
のインスタンスを作成する際に、値が UNIX タイムスタンプに正規化されるからです。
ほとんどのメソッドで、引数 $part
に定数を指定できます。
これにより、日付のどの部分を選択するかを指定します。この定数は、
たとえば Zend_Date::HOUR
のようになります。
これらの定数は、以下のすべての関数で使用できます。使用可能なすべての定数の一覧は
項8.5.2. 「全定数の一覧」 にあります。
$part
を省略した場合は、Zend_Date::TIMESTAMP
が指定されたものとみなします。また、ユーザ定義の書式を
$part
で使用することもできます。ここには、
Zend_Locale_Format::getDate()
と同様のコードを使用します。
日付オブジェクトが明らかに無効な値を用いて作成された場合 (たとえば月が 12 より大きいなど) は、
Zend_Date
は例外をスローします。ただし、特定の日付フォーマットが指定されている場合、
つまり $part
が null
あるいは Zend_Date::DATES
("あいまいな" フォーマット)
のいずれかである場合は別です。
例 8.8. ユーザ定義の入力日付書式
<?php $date1 = new Zend_Date('Feb 31, 2007', null, 'en_US'); echo $date1, "\n"; // 出力は "Mar 3, 2007 12:00:00 AM" となります $date2 = new Zend_Date('Feb 31, 2007', Zend_Date::DATES, 'en_US'); echo $date2, "\n"; // 出力は "Mar 3, 2007 12:00:00 AM" となります $date3 = new Zend_Date('Feb 31, 2007', 'MM.dd.YYYY'); // 指定したフォーマットで解釈するように強制します echo $date3, "\n"; // 出力は "Mar 3, 2007 12:00:00 AM" となります ?>
オプションのパラメータ $locale
を指定すると、
その $locale
をもとに $date
オペランドを解決します。
つまり、日付文字列に含まれる月名や曜日名などを、そのロケールにあわせて適切に解釈します
(
Zend_Locale_Format::getDate()
を参照ください)。
各地域固有の形式の文字列で $date
オペランドが指定された際に
自動で正規化が行われるのは、$part
が
定数 Zend_Date::DATE*
あるいは Zend_Date::TIME*
のいずれかであるときです。
$date
が日付を含む文字列の場合は、
月名や曜日名をパースする際に使用する言語はロケールをもとに決定します。
入力パラメータ $date
が指定されなかった場合は、
$locale
パラメータの内容をもとにして地域化した結果
(日付書式を文字列で表したもの) を出力します。
入力パラメータ $date
に具体的な型が指定されている場合もあります
(たとえば addHour()
では $hour
です)。
このような場合でも、引数として Zend_Date
オブジェクトを使用できることに注意しましょう。
$locale
を指定しなかった場合は、
現在のオブジェクトのロケールを使用して
$date
を解釈します。あるいは出力用書式を選択します。
メソッド add(), sub(), compare(), get(), and set()
は、日付全般に対して使用できます。それぞれのメソッドは、
そのインスタンスが保持する日付の値を操作します。
これらのメソッドのうち、get()
以外ではすべて $date
オペランドが必要となります。
ここには Zend_Date
のインスタンスか
数値文字列、あるいは整数値を指定します。
これらのメソッドで $date
にオブジェクト以外を指定した場合、
それはタイムスタンプであるとみなされます。
しかし、$part
オペランドを使用すると、
ふたつの日付データが日付のどの部分を表すものなのかを指定できます。
たとえば "年"、"分" などが指定できます。それだけではなく、
"December 31, 2007 23:59:59" のような長い形式の文字列も
$date
に指定できます。
compare()
および get()
以外のメソッドは、処理の結果としてオブジェクト内の日付が変更されます。
例 8.9. 日付要素の操作
<?php require_once 'Zend/Date.php'; $date = new Zend_Date(); // $date のタイムスタンプは time() の返す値と等しくなります // $date に 12 時間足します $date->add('12', Zend_Date::HOUR); print $date; ?>
基本的な操作について、一般的な日付要素と組み合わせて使用する際に
便利なメソッドが用意されています。
これらのメソッドを使用すると、上で説明したメソッドのように
日付要素の定数
をいちいちタイプする必要がなくなります。
好都合なことに、これらのメソッドの名前は
プレフィックス (基本操作の名前) とサフィックス (日付要素の名前)
を組み合わせた形式、たとえば addYear()
のようになっています。以下の一覧における、すべての
"日付要素" と "基本操作" の組み合わせが存在します。
たとえば "add" は、各要素について
addDay()
や addYear()
などといったメソッドが存在します。
これらの便利なメソッドの機能は、基本操作メソッドと同等です。
しかし、$date
オペランドに文字列や整数値を使用する場合は、
メソッド名のサフィックスが指す日付要素以外を指定することはできません。
つまり、$date
が文字列あるいは整数値の場合は、
$date
オペランドの単位が
メソッド名によって ("Year" や "Minute" などに) 決まるということです。
表 8.1. 日付要素
日付要素 | 説明 |
---|---|
Timestamp (タイムスタンプ) | UNIX タイムスタンプ。January 1st, 1970 00:00:00 GMT/UTC からの経過秒数です。 |
Year (年) | グレゴリオ暦の年 (例: 2006)。 |
Month (月) | グレゴリオ暦の月 (1-12、各地域固有の名前もサポートしています)。 |
24 hour clock (24 時間の時間) | その日の時間 (0-23)。これは、その日がはじまってからの経過時間数を表します。 |
minute (分) | 時間内の分 (0-59)。これは、その時間がはじまってからの経過分数を表します。 |
Second (秒) | 分内の秒 (0-59)。これは、その分が始まってからの経過秒数を表します。 |
millisecond (ミリ秒) |
ミリ秒 (0-999)。これは、千分の一秒を表します。
Zend_Date では、秒未満の単位を扱うために
二つのメソッドを用意しています。デフォルトでは、
Zend_Date のインスタンスはミリ秒単位の精度を使用します。
これは getFractionalPrecision() を使用して取得します。
精度を変更するには setFractionalPrecision($precision)
を使用します。しかし、精度は事実上ミリ秒までに制限されます。
というのも、Zend_Date は
microtime()
を使用しているからです。
|
Day (日) |
Zend_Date::DAY_SHORT は $date
から抽出します。これは、$date オペランドが
Zend_Date のインスタンスであるか、
あるいは数値文字列である場合に行われます。
それ以外の場合は、以下の定数によって指定した規約に基づいて抽出します。
Zend_Date::WEEKDAY_NARROW 、Zend_Date::WEEKDAY_NAME 、
Zend_Date::WEEKDAY_SHORT 、
Zend_Date::WEEKDAY (グレゴリオ暦とみなして処理します)。
|
Week (週) |
Zend_Date::WEEK は $date
から抽出します。これは、$date オペランドが
Zend_Date のインスタンスであるか、
あるいは数値文字列である場合に行われます。
それ以外の場合は例外が発生します (グレゴリオ暦とみなして処理します)。
|
Date (日) |
Zend_Date::DAY_MEDIUM は $date
から抽出します。これは、$date オペランドが
Zend_Date のインスタンスである場合に行われます。
それ以外の場合は、文字列 $date
を正規化して Zend_Date::DATE_MEDIUM 形式の日付にしようとします。
Zend_Date::DAY_MEDIUM の書式は、
そのオブジェクトのロケールに依存します。
|
Weekday (曜日) |
曜日は、0 (日曜日) から 6 (土曜日) までの数字で表されます。
Zend_Date::WEEKDAY_DIGIT は $date
から抽出します。これは、$date オペランドが
Zend_Date のインスタンスであるか、
あるいは数値文字列である場合に行われます。
それ以外の場合は、以下の定数によって指定した規約に基づいて抽出します。
Zend_Date::WEEKDAY_NARROW 、Zend_Date::WEEKDAY_NAME 、
Zend_Date::WEEKDAY_SHORT 、
Zend_Date::WEEKDAY (グレゴリオ暦とみなして処理します)。
|
DayOfYear (年内の日数) |
Zend_Date では、これは年初からの経過日数
(0-365) を表します。これまでの他の単位と同様、
端数は切り捨てられます (グレゴリオ暦とみなして処理します)。
|
Arpa |
Arpa 日付 (つまり RFC 822 形式の日付) をサポートしています。
出力形式は、"GMT" あるいは "地方時 + 時差" 形式になります
(RFC 822 の section 5 を参照ください)。
PHP 5.2.2 より前のバージョンでは、定数 DATE_RFC822 を
PHP の日付関数で使用したときに
おかしな結果
となる場合がありました。Zend_Date は、正しい結果を返します。
例: Mon, 31 Dec 06 23:59:59 GMT
|
Iso |
出力形式として、完全な ISO 8601 日付のみをサポートしています。
例: 2009-02-14T00:31:30+01:00
|
便利なメソッド群ではなく以下の基本操作を使用する場合には、
適切な定数
を $part
パラメータで指定します。
表 8.2. 基本操作
基本操作 | 説明 |
---|---|
get() |
get($part = null, $locale = null)
|
set() |
set($date, $part = null, $locale = null)
ロケール |
add() |
add($date, $part = null, $locale = null)
ロケール |
sub() |
sub($date, $part = null, $locale = null)
ロケール |
copyPart() |
copyPart($part, $locale = null)
オブジェクトの複製を返します。もとのオブジェクトの日付のうち
|
compare() |
compare($date, $part = null, $locale = null)
|
以下の基本操作については、 項8.4. 「Zend_Date API の概要」 の一覧にある各日付要素に特化した便利なメソッドは存在しません。
表 8.3. 日付の比較用メソッド
メソッド | 説明 |
---|---|
equals() |
equals($date, $part = null, $locale = null)
ロケール |
isEarlier() |
isEarlier($date, $part = null, $locale = null)
このオブジェクトの日付要素 |
isLater() |
isLater($date, $part = null, $locale = null)
このオブジェクトの日付要素 |
isToday() |
isToday() 今日の年月日が、このオブジェクトの日付と一致するかどうかを調べます (このオブジェクトのタイムゾーンを用いて判断します)。 |
isTomorrow() |
isTomorrow() 明日の年月日が、このオブジェクトの日付と一致するかどうかを調べます (このオブジェクトのタイムゾーンを用いて判断します)。 |
isYesterday() |
isYesterday() 昨日の年月日が、このオブジェクトの日付と一致するかどうかを調べます (このオブジェクトのタイムゾーンを用いて判断します)。 |
isLeapYear() |
isLeapYear()
|
isDate() |
isDate($date, $format = null, $locale = null) このメソッドは、指定した日付が本当に日付であるかどうかを調べ、 すべてのチェックを通過したときに true を返します。 PHP の checkdate() 関数と似たような働きですが、各地域固有の月名にも対応しており、 また checkdate() の対象範囲外の日付でも正しく判定できます。 |
Zend_Date
インスタンスに関する情報の取得をサポートするメソッド群について説明します。
表 8.4. 日付出力用のメソッド
メソッド | 説明 |
---|---|
toString() |
toString($format = null, $locale = null)
直接実行することもできますし、マジックメソッド |
toValue() |
toValue($part = null)
指定した日付要素 |
get() |
get($part = null, $locale = null)
このメソッドは、オブジェクトの日付要素 |
now() |
now($locale = null)
この関数は、 |
Zend_Date
インスタンスに関する情報の取得をサポートするメソッド群について説明します。