WEB相談室

Webページ作成に関しての何でも掲示板です。

タイトル:時間の判定方法

ゆう [WriteDate : Mon May 21 00:39:53 2001]

おせわになっています、ゆうです。
今僕はメル友サイトを作っています。
そこで行き詰まっている部分があります。
それは、登録してから7日間のデータにはNEWマークを、
そして更新してから7日間のデータにはRENEWマークを
付けたいと思い、例えば、登録日が20日で27日までは
NEWマークが付いて28日にはNEWマークが付かないっていう
所までは出来ているんですけど、例えば登録日が25日の
場合NEWマークは7日間付けるため、次の月の2日までNEW
マークを付けたいんですけど、自分ではどうしてよいのか
わかりません。
どなたかご教授の程よろしくお願い致します。


Nobu3 [URL] [WriteDate : Mon May 21 01:02:44 2001]

7日間って何秒間?


ゆう [WriteDate : Mon May 21 01:10:24 2001]

7日間は604800秒ですけど、月が同じで、現在の日にち>登録日+7日
という条件の場合は上手くいくんですけど、月が違って現在の日にち<登録日+7日
の場合はどう判断すればいいのか思いつかないのです。
ホントの初心者ですみません。


Nobu3 [URL] [WriteDate : Mon May 21 01:49:22 2001]

いや、だから「秒」で計算したらいいんじゃ?
言語は何かしらないけど、timeかなんかで「いついつからの秒数」を取得できると思う。


ゆう [WriteDate : Tue May 22 01:09:25 2001]

Nobu3さんご教授ありがとうございます。
これで基準の方はわかりましたが、比較する方を秒に直す方法はあるんでしょうか?
試しに(年-1970)×365+月×31+日と計算して表示してみたら、timeと32日ほど、差が出てしまいました。
この差は閏年や1月が31日あって2月が28日しかないなどの差なのでしょうが。
この差を埋めてグリニッジの時間表示→秒に逆に変換する方法ってないのでしょうか?
例、2001年5月22日を990460727秒などという風に変換する方法


Nobu3 [URL] [WriteDate : Tue May 22 01:25:20 2001]

Perlならば「とほほのWWW入門」の
http://tohoho.wakusei.ne.jp/wwwsoft.htm
にある「WwwLounge Ver2.13」の「wwwlng.cgi」に「mktime」というサブルーチン(1105行目から)があります。
呼び出し元は794行目です。
どんな計算をやっているかは、ソースを見ればなんとなくわかると思います。


ゆう [WriteDate : Tue May 22 02:59:18 2001]

何度もすみません。このとほほのソースを見た限りでは、mktimeサブルーチンの中では
マイナスを加算していますが、これを生かしている部分を見つけることができませんでした。
呼び出してある、794行目[$mtime = &mktime($1 - 1900, $2 - 1, $3, $4, $5, $6, -9);]
をprintしてみても、「-62139776400」という風にかなりの数のマイナスの数が表示されます。


The WAY [URL] [WriteDate : Tue May 22 03:51:34 2001]

>この差を埋めてグリニッジの時間表示→秒に逆に変換する方法ってないのでしょうか?
>例、2001年5月22日を990460727秒などという風に変換する方法

モジュール Time::Local を使うのが最も簡単。

# ===== テストコード =====

use Time::Local;

# 判別用サブルーチン。
# 引数は (年, 月, 日, 時, 分, 秒) 。
# 登録が 7 日以内であれば 1 を、そうで無ければ 0 を返す。
sub hanbetsu ($$$$$$) {
     my($year, $mon, $day, $hour, $min, $sec) = @_;
     $regTime = timelocal($sec, $min, $hour, $day, $mon-1, $year-1900);
     return (time - $regTime <= 7*24*60*60) ? 1 : 0;
}

# 2001/05/22 00:00:00 の場合。
print hanbetsu(2001, 5, 22, 0, 0, 0);  # 1
# 2001/05/12 00:00:00 の場合。
print hanbetsu(2001, 5, 12, 0, 0, 0);  # 0


Nobu3 [URL] [WriteDate : Tue May 22 09:19:54 2001]

その$1から$6までは、その呼出し行の直前にある正規表現の結果なので、実際には
&mktime($year - 1900, $mon - 1, $day, $hour, $min, $sec, $tz);
ということです。

ちなみに、The Wayさんが見本として書いたサブルーチンをmktime用に書きなおすと…
sub hanbetsu ($$$$$$) {
    my($year, $mon, $day, $hour, $min, $sec) = @_;
    $regTime = mktime($year-1900, $mon-1, $day, $hour, $min, $sec, -9); # この行だけ変更
    return (time - $regTime <= 7*24*60*60) ? 1 : 0;
}
となります。
ただ、こっちだと日本時間しか計算できないので、モジュールを使えるのならばこっちを無視した方が賢明です。


ゆう [WriteDate : Wed May 23 00:56:59 2001]

Nobu3さんTHE WAYさんありがとうございます。
僕が使っている環境ではモジュールが使えるのかどうかわかりません。
jcode.plやcgi-lib.plとはまた違ったものなんですよね?
今sub hanbetsuをtime.cgiという名前にしてやってみたんですけど、
telnetで「time.cgi: syntax error at line 1: `(' unexpect」
という風にエラーが出てきてしまいます。


Nobu3 [URL] [WriteDate : Wed May 23 01:55:22 2001]

syntax error
文法エラーです。

1行目で変な事してますか?なんか「(」がどうのこうのと言ってるようですが、括弧の組数とか合ってますか?


ゆう [WriteDate : Wed May 23 02:18:47 2001]

sub hanbetsu ($$$$$$) {処理}
この$$$$$$の部分は自分で勝手に決めた変数でよろしいんですか?
そして、($$$$$$)を消して見たら、今度は
syntax error at line 2: `my' unexpected
という風に2行目のmy関数の部分で文法エラーが出てしまったんですけど、
2行目は
my($year, $mon, $day, $hour, $min, $sec) = @_;
なんですけど。


The WAY [URL] [WriteDate : Wed May 23 02:35:36 2001]

つーか CGI で動かすんなら 1行目は Perl への Path でしょ?
あるいは telnet で `perl test.cgi' とか。


ゆう [WriteDate : Wed May 23 02:46:44 2001]

これはサブルーチンとして外部から読み込んで使っているんです。
本隊のCGIファイルを実行してもinternal server errorが出てしまいます。


The WAY [URL] [WriteDate : Wed May 23 03:16:57 2001]

読み込んで使っているという事は、ライブラリにして require してるってことですか?

…と書きあってても埒があかないので、スクリプトの実物を公開していただくと解決が早いかもしれません。


The WAY [URL] [WriteDate : Wed May 23 03:17:06 2001]

読み込んで使っているという事は、ライブラリにして require してるってことですか?

…と書きあってても埒があかないので、スクリプトの実物を公開していただくと解決が早いかもしれません。


ゆう [WriteDate : Thu May 24 01:10:23 2001]

The WAYさん返答ありがとうございます。
読み込んで使っていると言うのはThe WAYさんの察しの通りrequireしています。
今自分のスクリプトで時間処理の部分だけ、抜き出してみました。
このままではまだInternal Server errorが出ています。
telnetで実行すると、表示されるんですけど。

スクリプトは以下の通りです。
このままでは不完全も程々にしてくれと言うくらいモノだと思いますが、
勘弁して下さい。

#!/usr/local/bin/perl

require './../jcode.pl';

Time::Local;

$data = time;
print "<html>";
print "t $data";
$mtime = &mktime($1 - 1900, $2 - 1, $3, $4, $5, $6, -9);
print "mt $mtime";

print "times($r)";
print "</html>";
exit;


sub times ($r) {
    my($year, $mon, $day, $hour, $min, $sec) = @_;
    $regTime = mktime($year-1900, $mon-1, $day, $hour, $min, $sec, -9);
    return (time - $regTime <= 7*24*60*60) ? 1 : 0;
}

sub mktime #($year, $mon, $mday, $hour, $min, $sec, $tz)
{
   local($year, $mon, $mday, $hour, $min, $sec, $tz) = @_;
   local(@mdays, $xtime);

   @mdays = ( 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334);
   $uru = int(($year - 72) / 4);
   if (((($year + 1900) % 4) == 0) && ($mon < 2)) { $uru--; }
   $xtime = $year - 70;
   $xtime = ($xtime * 365) + $mdays[$mon] + $mday + $uru;
   $xtime = ($xtime * 24) + $hour + $tz;
   $xtime = ($xtime * 60) + $min;
   $xtime = ($xtime * 60) + $sec;
   return($xtime);
}

このまま$mtimeを表示すると、-62139776400という結果を出力します。
それと、今使っているtimesというサブルーチンの
sub times ($$$$$$){処理;}
の$$$$$$の意味が未だに理解できません。
ホントに勉強不足だとはわかっているんですけど、よろしくお願い致します。


The WAY [URL] [WriteDate : Thu May 24 01:55:40 2001]

というか、私の書いたスクリプトはそのスクリプトの中で完結しているので、mktime と一緒に使われても困ります。
私のサブルーチンは当初の目的で言う所の「NEWがつく時」に 1 を、そうで無い時には 0 を返すもので、具体的な秒数は返しません。

>Time::Local;
モジュールを使う時には `use Time::Local;' と前に `use' をつけて下さい。

>sub times ($$$$$$){処理;} の$$$$$$の意味
これは「引数にスカラー値を6つ取りますよ」というものですが、省略可能です。
# なので、邪魔だったら消して下さい。

で、times の引数は6つです。
$r というのが何を指すのかはわかりませんが、(年, 月, 日, 時, 分, 秒) で指定して下さい。
違う指定法がいい場合はその旨をお願いします。


ゆう [WriteDate : Fri May 25 01:10:38 2001]

ホントに理解不能なことばかりやってしまっていてすみません。
今試したモノは、以下と同じモノなんですけど、

#!/usr/local/bin/perl

require './../jcode.pl';

use Time::Local;
$data =  &times;
print "Content-type: text/html\n\n";
print "<html>";
print "d $data";
print "</html>";
exit;

sub times ($$$$$$) {
    my($year, $mon, $day, $hour, $min, $sec) = @_;
    $regTime = timelocal($sec, $min, $hour, $day, $mon-1, $year-1900); # line18
    return (time - $regTime <= 7*24*60*60) ? 1 : 0;
}

Day '' out of range 1..31 at link.cgi line 18
Month '-1' out of range 0..11 at link.cgi line 18
と言ったようなエラーがtelnetで検出されてしまいます。

The WAYさんが教えてくれたモジュールを使った方を取り入れようと考えていますが、
僕が今やっている$data =  &times;というやり方で、$dataを出力しようとする方法は
よいのでしょうか?今エラーが出ているままなので、試しにline18を注釈行として、
実行したら、(time - $regTime <= 7*24*60*60)を完全に見たいしているのでちゃんと
1を返してくれましたが、$regTimeの方が完全ではないので、0を返すテストが出来ない
状態であります。


The WAY [URL] [WriteDate : Fri May 25 01:48:21 2001]

times の引数は?
ちゃんと引数を取って下さい、という事は前回も書いたんですけど。

>僕が今やっている$data =  &times;というやり方で、$dataを出力しようとする方法はよいのでしょうか?
よいです。


ゆう [WriteDate : Sat May 26 01:41:33 2001]

The WAYさん、ホントにありがとうございます。
cgiファイル単体の場合は成功しました。
しかし、複数の場合がinternal server errorには
ならないんですけど、論理エラーと言っていいのかは
わかりませんが、表示してくれません。

time.cgiのソース

#!/usr/local/bin/perl

sub times ($$$$$$) {
    ($ymd,$hms) = split(/(/,$date2);
    $hms =~ s/\D//gi;
    ($year,$mon,$day) = split(/(/,$ymd);
    ($hour,$min,$sec) = split(/(/,$hms);
    $nowdate = time;
    $regTime = timelocal($sec, $min, $hour, $day, $mon-1, $year-1900);
    return ($nowdate - $regTime <= 7*24*60*60) ? 1 : 0;
}

1;

そしてレイアウト表示
layout.cgiのソース

tableなどのタグがこの部分にあります。
ちょっと省略

$data = &times;   #1

if($date eq $date2 && $data == 1){
print <<"LAYOUT_DATE";

    <b><font color="0044ff">NEW!!</font></b>

LAYOUT_DATE
} elsif($data == 1){
print <<"LAYOUT_DATE2";

    <b><font color="0044ff">RENEW!!</font></b>

LAYOUT_DATE2
}

</table>
などの閉じるタグがあります。

そして最後はサブルーチンなので、
}
1;
で終わっています。

time::local;は本体cgiのpathの後に記入しています。
dateには登録時間が、date2には更新時間が入っています。
time.cgiもlayout.cgiもrequireであらかじめ呼び出しています。

#1の部分を注釈行にせず、実行すると、layout.cgiが途中で止まって
しまいます。しかし、#1の1行を注釈行にすると、ちゃんとlayout.cgiは
最後まで表示されます。やっぱりサブルーチンに分けるのはまずいやり方なんでしょうか?


The WAY [URL] [WriteDate : Sat May 26 02:36:59 2001]

>dateには登録時間が、date2には更新時間が入っています。
例えばどんな値になるかを示して下さい。

>やっぱりサブルーチンに分けるのはまずいやり方なんでしょうか?
それが原因でエラーになることは無いです。
# jcode.pl はサブルーチンのカタマリですが、それを使ってもエラーにはならない
あくまでも &times の書き方、あるいは &times の呼び出し方の問題でしょう。

`use Time::Local;' は test.cgi に書いた方がいいと思います。

あと sub times のあとの ($$$$$$) はいらないです。(理由は前の通り)
失礼ですが、「引数」の意味はわかりますか?
どうもこのあたりで話が通じていない気がするのですが。


ゆう [WriteDate : Sun May 27 01:45:24 2001]

ホントに迷惑ばかり掛けてすみませんでした。
エラーの原因はsplitのミスでした。The WAYさんのおっしゃるとおり、呼び出し方に問題がありました。

そこを直したらちゃんとサブルーチンに分けても成功しました。
本当に丁寧に説明していただきありがとうございます。

引数のことですが、サブルーチンを挟んだ場合、いまいち理解出来ていないです。


The WAY [URL] [WriteDate : Mon May 28 00:40:33 2001]

>サブルーチンを挟んだ
の意味がちょっと理解できませんでした。
が、サブルーチンの使い方は、別ファイルに分けようが分けまいが基本的には一緒です。
詳しくは本などで参照して下さい。


ゆう [WriteDate : Mon May 28 07:59:17 2001]

サブルーチンを挟んだって言い方ちょっと悪かったですね。
跨いだと言ったほうが正しいです。

引数のことは本で調べます。
本当に今まで親切丁寧にご指導していただきありがとうございました。

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]
ChaichanPAPA's World