MIME::Lite用の時刻文字列生成
スポンサードリンク
MIME::Liteで普通にメールを生成すると、
Date: Mon, 23 Jul 2008 10:00:00 UT
ていうヘッダが入ってイヤだ、という話題。何がイヤだか、ていうと、日本標準時(JST)でないので、Dateヘッダをそのまま採用するMUA(Mozilla Thunderbirdなど)でプリントアウトすると時刻が直感的にわからんのです。
最近入稿システムのメール連絡を面倒だからといって今までMIME::EntityでプログラムしていたところをMIME::Liteで組んでみたら発生した。Liteたるゆえんか。
再現コードどうぞ。
use strict; use warnings; use utf8; use Encode; use MIME::Lite; use HTTP::Date; my $msg = MIME::Lite->new( From => 'from@example.com', To => 'to@example.com', Subject => Encode::encode('MIME-Header-ISO_2022_JP', 'コンニチワ'), # EncodeでMIME-Header-ISO_2022_JPが使えるのは # Perl5.8.6以降同梱のもの Type => 'text/plain; charset="ISO-2022-JP"', Encoding => '7bit', Data => encode('iso-2022-jp', '元気でやってるかー?'), ); $msg->send();
上記コードではDateヘッダ入れていませんが、MIME::Liteで勝手に現在時刻から入れます。それが、UT(世界時)になってしまう罠。
というわけで、MIME::Liteには、Dateヘッダを自分で設定するためのオプションとして、Datestamp => 0 を指定する方法がありますので、自分で時刻文字列作ってしまうことで、DateヘッダがUT(世界時)になることを防げます。
use strict; use warnings; use utf8; use Encode; use MIME::Lite; use HTTP::Date; my $msg = MIME::Lite->new( From => 'from@example.com', To => 'to@example.com', Subject => Encode::encode('MIME-Header-ISO_2022_JP', 'コンニチワ'), # EncodeでMIME-Header-ISO_2022_JPが使えるのは # Perl5.8.6以降同梱のもの Type => 'text/plain; charset="ISO-2022-JP"', Encoding => '7bit', Data => encode('iso-2022-jp', '元気でやってるかー?'), Datestamp => 0, Date => 'Mon, 23 Jun 2008 20:00:00 +0900', ); $msg->send();
なんてかんじにするとヘッダに好きな時刻を設定できます。
さて、時刻文字列を作る方法ですが、5つぐらい探しました。
#!/usr/bin/perl use strict; use warnings; sub datestr0 { # UNIXのdateコマンド使う方法 # dateコマンドの動作が違と動かない (local $_ = `date -R`) =~ s/\n//sgo; return $_; } sub datestr1 { # モジュールを使わない方法 # via http://tech.bayashi.net/pdmemo/sendmailbyperl.html my ( $sec, $min, $hour, $mday, $mon, $year, $wday ) = localtime( time ); my @week = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); my @month = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ); my $d = sprintf( "%s, %d %s %04d %02d:%02d:%02d +0900", $week[$wday], $mday, $month[$mon], $year + 1900, $hour, $min, $sec, ); return $d; } sub datestr2 { # HTTP::Dateモジュールを使用 # via http://ja.doukaku.org/24/nested/ use HTTP::Date; my $tz = +9; ( my $date = HTTP::Date::time2str( time + $tz * 3600 ) ) =~ s/GMT/sprintf( '%+03d00', $tz )/e; return $date; } sub datestr3 { # Date::Manipモジュールを使用 # via http://search.cpan.org/~sbeck/Date-Manip-5.54/lib/Date/Manip.pod use Date::Manip; return UnixDate('today', '%g'); } sub datestr4 { # DateTime::Format::Mailモジュールを使用 # via http://search.cpan.org/~sbeck/Date-Manip-5.54/lib/Date/Manip.pod use DateTime; use DateTime::Format::Mail; return DateTime::Format::Mail->format_datetime( DateTime->now( time_zone => 'Asia/Tokyo', ) ); } print datestr0()."\n"; print datestr1()."\n"; print datestr2()."\n"; print datestr3()."\n"; print datestr4()."\n"; __END__
実行結果:
$ perl date.pl Mon, 23 Jun 2008 19:49:23 +0900 Mon, 23 Jun 2008 19:49:23 +0900 Mon, 23 Jun 2008 19:49:23 +0900 Mon, 23 Jun 2008 19:49:24 +0900 Mon, 23 Jun 2008 19:49:24 +0900 $
それぞれの評価:
datestr0 | バッククオート演算子 | 危ないので使用禁止 |
datestr1 | Perlのみ | テッパン |
datestr2 | HTTP::Dateモジュール | 割と素直。環境依存しにくい |
datestr3 | Date::Manipモジュール | 一番楽だがWindowsだと動かない可能性あり |
datestr4 | DateTime::Format::Mailモジュール | プログラム内でDateTime使ってしまったときについでに使う。 |
こう書いていると、なんだか大がかりになってきたので、普通にMIME::Entity使った方が楽なんじゃないかという気にもなってきました。
スポンサードリンク
トラックバック(0)
トラックバックURL: http://blog.dtpwiki.jp/MTOS/mt-tb.cgi/2511
コメントする