Zend_DateでHTTP日付を出力2007年11月15日 22時02分13秒

Zend_Dateのコネタでやす。

HTTP日付って?

昨日今日と、ちょっとIEのタコっぷりにやられてた都合で(あとで書くかも)、PHPから Last-Modified をレスポンスヘッダに出力してやる必要があったので、ちょっと調べてみた。

検索して引っかかったこちらのサイトの記述によると、

Last-Modified = "Last-Modified" ":" HTTP-date
ってな定義らしい。んで、この「HTTP-date」は、
リソースの最終更新時刻を記述するためのフィールドです。ここに指定する時刻は、HTTP 日付を使用しなければなりません。
だそうな。サンプルを見ると、
Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
てな出力になる。

んで、さらにここのサイトさんはHTTP日付についても掲載していてくれて、それによると、

最初のフォーマットはインターネット標準としてより好まれ、RFC 1123 (RFC 822 の改定) にて定義される固定長サブセットを表す。
ってな話らしい。要するにRFC 822か、RFC 1123の形式で出力できればよさげ。

Zend_Dateでいけるかにゃー

ZFのマニュアル「9.6 日付関数全般の定数」をつらつら眺めると、「表 9.14. 日付フォーマットに関する定数 (タイムゾーンを含むフォーマット)」に、

  • Zend_Date::RFC_822
  • Zend_Date::RFC_1123
  • なんて、そのままズバリの定数があるので、これをZend_Date::get()に渡せばよかろうと。

    <php
    require_once 'Zend/Date.php';
    
    $date = new Zend_Date('2007/11/15');
    echo $date->get( Zend_Date::RFC_1123 );
    
    とやったら、出力は
    Thu, 15 Nov 2007 00:00:00 +0900
    
    
    となった。これでいいのかと思いきや、
    全ての HTTP 日付/時刻スタンプは、例外を除いてグリニッジ標準時刻 (GMT) で表されなければならない。
    なんてあるじゃないですか!タイムゾーンを設定せねば。

    Zend_Dateにタイムゾーンを設定してみる

    Zend_Dateには「getTimeZone()」やら「setTimeZone()」なんてメソッドがあるので、これ使えばいいかと。

    ただ、マニュアルに載ってるサンプルコードは特定のタイムゾーンに設定するものばかりで、明示的にGMTを設定するコードが載ってない。はて、どうしたもんかと30秒くらい悩んだ挙句、ダメもとで文字列'GMT'と渡してみることに。

    $date->setTimeZone( 'GMT' );
    echo $date->get( Zend_Date::TIMEZONE_NAME );
    
    // -> 'GMT'
    
    
    あら、ビンゴ。んじゃさっきのZend_Date::RFC_1123と組み合わせてみるか。
    $date->setTimeZone( 'GMT' );
    echo $date->get( Zend_Date::RFC_1123 );
    
    // -> 'Wed, 14 Nov 2007 15:00:00 +0000'
    
    
    って、「+0000」ってなんやねん。

    なんとか「GMT」と出力したい

    このままほっとこうかなーとも思ったが、クライアントが意図どおり解釈してくれるかちと不安になったので、なんとか「+0000」を「GMT」に変えて出力したい。

    もちろん、細かく書式指定子を与えれば欲しい出力が得られるのはわかってるんだけど、なるたけ不精したいじゃない。

    なんとかならんかとまた「 9.6 日付関数全般の定数」をつらつら眺めたら、「表 9.13. タイムゾーンに関する定数」におあつらえ向きの「Zend_Date::GMT_DIFF」なんてのが載ってたので、どんな出力になるのか試してみた。

    echo $date->get( Zend_Date::GMT_DIFF );
    
    // -> '+0000'
    
    
    おし、思ったとおり「+0000」の出力が得られた!これを単純に'GMT'に置き換えればいいワケだ。多分。

    そんなこんなで結論

    置換は特に問題ないだろうと思うので、シンプルにstr_replace()を使うことにして、最終的には、こんな感じになった。

    <php
    require_once 'Zend/Date.php';
    
    $date = new Zend_Date('2007/11/15');
    
    // タイムゾーン設定
    $date->setTimeZone( 'GMT' );
    
    echo str_replace(
    	$date->get( Zend_Date::GMT_DIFF ),      // search => '+0000'
    	$date->get( Zend_Date::TIMEZONE_NAME ), // replace => 'GMT'
    	$date->get( Zend_Date::RFC_1123 )
    );
    
    // -> 'Wed, 14 Nov 2007 15:00:00 GMT'
    
    
    ...でも、ちと面倒くさいなーー。このくらいのフォーマット用定数、用意しておいてよ > Zend_Date

    余談

    前にZend_Date取り上げた時のエントリのタイトル、「Zend_Dete」って...orz

Inkscapeの出力したsvgに注意2007年11月15日 22時25分45秒

「セキュリティ」ってカテゴリが正しいのかは置いといて。

こないだPOSTした「Inkscapeでアクア風ボタンを作ってみる」で、作成したSVGを公開したんだけど、テキストエディタで中身をのぞいてちとびっくり。 ルート要素の「svg」に「sodipodi:docbase」って属性がくっついてて、そこに作成時のローカルディレクトリのパスが入ってるじゃない!

てなわけで、差し替えました。あー、びっくり。

まぁ、これ覗かれたからって、即なんか危ないわけじゃないんだけど、Inkscapeで作成したファイルを配布するときはご注意を。不要にローカルの情報を外部に出す必要ないしね。

なんか出力を抑制するオプションがあるのかしらん。

完全にカブっとるがな!2007年11月15日 22時55分25秒

Inkscapeでアクア風ボタンを作ってみる」、こちらの記事と完全にカブってますがな!!

FFFさんのほうが「レイヤー効果」代わりの処理を細かくやってるし、説明もdara-jより丁寧なので、こちらを参考にしたほうがよいかも。

どっからどうみてもほぼ同じ手順。しかも半年近く前の記事だし。まるで自分がパクったみたいでかなりヘコむ。

パクってないよなぁ > 俺。