warning: Creating default object from empty value in /var/www/drupal-5.23/modules/taxonomy/taxonomy.module on line 1418.

Perl で、誕生日を求める。

my $now = time; とすれば、$now に 「1970 年 1 月 1 日から現在までの秒数」 の値が入る。そこで、ある人の誕生日を 1970 年からの秒数としてデータベースに保存してある場合は、現在の時刻から誕生日の時刻を引き算してあげて年(365 日)、日(24 時間)、時(60 分)、分(60 秒)で割ってあげた整数値(int)を計算すれば、誕生日が求まるような気がする。しかしすぐに気づくのだがこの方法だけではうるう年が勘案されていないから、正確な誕生日は求められない。単純に 365 で割ったのでは誤差が出てしまうのである。 そこでどうすればいいかというと、365 という値を 「1年の正確な日数」 にして割ればよい。1 年というのは正確には 365.2425 日らしいので、「生年月日から現在までの日数」 を 「365.2425」 で割れば、正確な年齢を求めることができる。
#!/usr/bin/perl -w

use Time::Local;

$year = 1980;
$mon = 8;
$day = 24;

my $birthday = timelocal(0, 0, 0, $day, $mon - 1, $year);
$age = int((time - $birthday) / 365.2425 / 24 / 60 / 60);

print $age;

1;
my $now = time; とすれば、$now に 「1970 年 1 月 1 日から現在までの秒数」 の値が入る。そこで、ある人の誕生日を 1970 年からの秒数としてデータベースに保存してある場合は、現在の時刻から誕生日の時刻を引き算してあげて年(365 日)、日(24 時間)、時(60 分)、分(60 秒)で割ってあげた整数値(int)を計算すれば、誕生日が求まるような気がする。しかしすぐに気づくのだがこの方法だけではうるう年が勘案されていないから、正確な誕生日は求められない。単純に 365 で割ったのでは誤差が出てしまうのである。 そこでどうすればいいかというと、365 という値を 「1年の正確な日数」 にして割ればよい。1 年というのは正確には 365.2425 日らしいので、「生年月日から現在までの日数」 を 「365.2425」 で割れば、正確な年齢を求めることができる。
#!/usr/bin/perl -w

use Time::Local;

$year = 1980;
$mon = 8;
$day = 24;

my $birthday = timelocal(0, 0, 0, $day, $mon - 1, $year);
$age = int((time - $birthday) / 365.2425 / 24 / 60 / 60);

print $age;

1;

Perl で、RSS で配信されたエントリーの日付を処理する

HTTP::Date クラスを使うと RSS で配信されたエントリーの日付 (dc:date) を変換してくれる。この場合、RSS のソースによって米国から日本のニュースにアクセスした場合などは、時差 (タイムゾーン) を考慮する必要があるため注意する。 使用するクラス
use HTTP::Date;
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Date;

# 初期化
my $html;
my $timezone = 'JST';
my $url    = 'https://www.yoursite.com/index.rdf';
my $rss    = new XML::RSS;
my $proxy  = new LWP::UserAgent;       # UseAgent の作成
my $req    = new HTTP::Request(GET=>$url);
my $res    = $proxy->request($req);    # $url にアクセスする
my $xml    = $res->content;            # コンテンツ (この場合は RSS/XML) を取得

# RSS を解析
eval {
    $rss->parse($xml);
};

if($@) {
    # $rss->parse が失敗したとき
}

# @{$rss->{items}} に、RSS のすべてのエントリー (item) が入る
foreach my $item ( @{$rss->{items}} ) {

    my $date        = HTTP::Date::str2time($item->{dc}->{date}, $timezone);

    $html    .=    qq|<a href=$item->{link}>$item->{title}</a><br>\n|; # タイトルをリンクつきで出力
    $html    .=    qq|$description<br>|    if $item->{description};    # 概要 (description) を出力
    $html    .=    qq|[<a href=$item->{link}>続きを読む</a>]<hr size=1>\n|;
}

print $html;

1;
HTTP::Date クラスを使うと RSS で配信されたエントリーの日付 (dc:date) を変換してくれる。この場合、RSS のソースによって米国から日本のニュースにアクセスした場合などは、時差 (タイムゾーン) を考慮する必要があるため注意する。 使用するクラス
use HTTP::Date;
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Date;

# 初期化
my $html;
my $timezone = 'JST';
my $url    = 'https://www.yoursite.com/index.rdf';
my $rss    = new XML::RSS;
my $proxy  = new LWP::UserAgent;       # UseAgent の作成
my $req    = new HTTP::Request(GET=>$url);
my $res    = $proxy->request($req);    # $url にアクセスする
my $xml    = $res->content;            # コンテンツ (この場合は RSS/XML) を取得

# RSS を解析
eval {
    $rss->parse($xml);
};

if($@) {
    # $rss->parse が失敗したとき
}

# @{$rss->{items}} に、RSS のすべてのエントリー (item) が入る
foreach my $item ( @{$rss->{items}} ) {

    my $date        = HTTP::Date::str2time($item->{dc}->{date}, $timezone);

    $html    .=    qq|<a href=$item->{link}>$item->{title}</a><br>\n|; # タイトルをリンクつきで出力
    $html    .=    qq|$description<br>|    if $item->{description};    # 概要 (description) を出力
    $html    .=    qq|[<a href=$item->{link}>続きを読む</a>]<hr size=1>\n|;
}

print $html;

1;

Perl で、時刻のシリアル値を取得したい。

Time::Local モジュールを利用する。localtime や gmtime の逆を行う。
use Time::Local;
#!/usr/bin/perl

use Time::Local;

$time = timelocal($sec, $min, $hour, $day, $mon, $year);
$time = timegm   ($sec, $min, $hour, $day, $mon, $year);

1;
Time::Local モジュールを利用する。localtime や gmtime の逆を行う。
use Time::Local;
#!/usr/bin/perl

use Time::Local;

$time = timelocal($sec, $min, $hour, $day, $mon, $year);
$time = timegm   ($sec, $min, $hour, $day, $mon, $year);

1;

Perl で、世界時計を作りたい。

実はタイムゾーンの計算は自力でやると非常に難しい。なぜなら、例えば米国の場合は「3月の第2週の日曜日の午前2時」ならびに「11月の第1週の日曜日の午前2時」だったりするからだ。ちなみにウィキペディア(Wikipedia)によると、
2007年からは「包括エネルギー法案」の可決により期間が約1ヶ月延び、開始日は3月の第2日曜日、終了は11月の第1日曜日となることが決まっている。なお、議会で法案が通れば、その自治体は夏時間を使用しなくてもよいため、2005年現在、ハワイ州は州全体、アリゾナ州とインディアナ州では大半の自治体で夏時間を採用していない。
ということで、2007年3月からはそれまでの4月の第1週の日曜日~10月の最終週の日曜日から制度の変更があった。 さて、Perl でタイムゾーンを得るにはどうするかというと、Time::Timezone モジュールを使う。フォーマットは Time::CTime を使ってみた。 使用するモジュール
use Time::Timezone;
use Time::CTime;
#!/usr/bin/perl

print &getDateTime('JST');
print &getDateTime('GMT');
print &getDateTime('PST');

sub getDateTime {

    my $tz = shift;

    use Time::Timezone qw (tz_offset);
    use Time::CTime;
    return strftime("%Y/%m/%d %R", gmtime(time + tz_offset($tz)));
}

1;
実はタイムゾーンの計算は自力でやると非常に難しい。なぜなら、例えば米国の場合は「3月の第2週の日曜日の午前2時」ならびに「11月の第1週の日曜日の午前2時」だったりするからだ。ちなみにウィキペディア(Wikipedia)によると、
2007年からは「包括エネルギー法案」の可決により期間が約1ヶ月延び、開始日は3月の第2日曜日、終了は11月の第1日曜日となることが決まっている。なお、議会で法案が通れば、その自治体は夏時間を使用しなくてもよいため、2005年現在、ハワイ州は州全体、アリゾナ州とインディアナ州では大半の自治体で夏時間を採用していない。
ということで、2007年3月からはそれまでの4月の第1週の日曜日~10月の最終週の日曜日から制度の変更があった。 さて、Perl でタイムゾーンを得るにはどうするかというと、Time::Timezone モジュールを使う。フォーマットは Time::CTime を使ってみた。 使用するモジュール
use Time::Timezone;
use Time::CTime;
#!/usr/bin/perl

print &getDateTime('JST');
print &getDateTime('GMT');
print &getDateTime('PST');

sub getDateTime {

    my $tz = shift;

    use Time::Timezone qw (tz_offset);
    use Time::CTime;
    return strftime("%Y/%m/%d %R", gmtime(time + tz_offset($tz)));
}

1;