WEB相談室

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

タイトル:日付の制限

0:[投稿] レンダ [2002/04/24 18:48 ][環境:MAC+IE UNIX系+Perl]

初めまして。不躾ですが質問させてください。

●申込み日:
<INPUT TYPE=text NAME="**" SIZE=30>
●訪問予定日:
<INPUT TYPE=text NAME="**" SIZE=30>

「申込み日」に日付を入力したとして、
「訪問予定日」には申込み日付+3日以降でなければエラーを
出して、訪問予定日の入力制限をしたいのですが、どういった
スクリプトを書けば良いでしょうか?

perlでやりたいと思っているのですが、お分かりの方、
助言をお願いします。


1:[回答] kougamiteru [2002/04/25 15:26 ]

日付の書き方はどんな感じですか?
申し込み日が4月25日なら単に「25」ですか?


2:[回答] アブサミラノ [2002/04/25 15:38 ]

日付の書き方

2002/04/25
等で日付として認識させたいです。


3:[質問] アブサミラノ [2002/04/25 15:43 ]

あ、名前間違えた。
難しそうな質問だったので名前を変えて質問していました。
初めましてとか書いてごめんなさい。
以降アブサミラノです。


4:[回答] アブサミラノ [2002/04/25 15:56 ]

unless($name =~ /^(\d{4})\/(\d{2})\/(\d{2})/) {
   print "Content-type: text/html\n\n";
   print <<HTML1;
   <HTML>
   <HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
   </HEAD>
   <BODY>
    2002/22/22という風に入力してください。
   </BODY>
   </HTML>
HTML1
   exit;
}

if($name =~ /^(\d{4})\/(\d{2})\/(\d{2})/) {
   unless($mail =~ /^(\d{4})\/(\d{2})\/(\d{2})/) {
   print "Content-type: text/html\n\n";
   print <<HTML1;
   <HTML>
   <HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
   </HEAD>
   <BODY>
    3日目以降の日付を入力してください。
   </BODY>
   </HTML>
HTML1
   exit;
}
}

日付の制限がさっぱり分かってないまま書いたスクリプトです。
これだと、数字だけには制限を付けられても、3日後の日付を
認識するどころではありません。ここからが分からず悩んでいます。


5:[回答] ふじ [URL] [2002/04/25 16:31 ]

こういう処理は、一旦秒単位(1970/1/1 からの秒数)に直して扱うのが定石でしょう。

use Time::Local;

# 申込日
$reg_time = timelocal(0, 0, 0, $reg_day, $reg_mon, $reg_year);

# 訪問予定日
$visit_time = timelocal(0, 0, 0, $visit_day, $visit_mon, $visit_year);

if($visit_time < $reg_time + 60 * 60 * 24 * 3){
   # 3日目以前
}


6:[回答] ふじ [URL] [2002/04/25 16:32 ]

あ、上の $reg_mon, $visit_mon は、月の数字から1を引いたものです。
1月なら 0、12月なら 11。


7:[質問] アブサミラノ [2002/04/27 10:43 ]

ふじさんへ

$reg_time = timelocal(0, 0, 0, $reg_day, $reg_mon, $reg_year);
↑この意味は、フォームから入力した2002/4/27などの日付を
秒数に直す、という意味ですよね?

ふじさんの助言をもとに、スクリプトを組んでみましたが、
エラーがでます。以下は私が組んだスクリプトです。

#!/usr/bin/perl

require './jcode.pl';
require './cgi-lib.pl';

&ReadParse(*FORM);
$reg_time = $FORM{'reg_time'};
$visit_time = $FORM{'visit_time'};
&jcode'convert(*reg_time, 'sjis');
&jcode'convert(*visit_time, 'sjis');

use Time::Local;

($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst)
    = localtime(time);
$mon++;
$date = $year . "年" . $mon . "月" . $day . "日\n";

# 申込日
$reg_time = &timelocal(0, 0, 0, $day, $mon, $year);

# 訪問予定日
$visit_time = &timelocal(0, 0, 0, $day, $mon, $year);

if($visit_time < $reg_time + 60 * 60 * 24 * 3){
 print "Content-type: text/html\n\n";
   print <<HTML1;
   <HTML>
   <HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
   </HEAD>
   <BODY>
    訪問予定日は申込日以前の日付は入力できません。
   </BODY>
   </HTML>
HTML1
   exit;
}

いろんな所が間違っているのでしょうが、どういった修正を
施せば良いか分かりません。
申し訳ありませんが、今一度助言をお願いします。


8:[回答] ふじ [URL] [2002/04/30 22:03 ]

> $reg_time = timelocal(0, 0, 0, $reg_day, $reg_mon, $reg_year);
> ↑この意味は、フォームから入力した2002/4/27などの日付を
> 秒数に直す、という意味ですよね?
そうです。あと、書きわすれましたが $reg_year は西暦の年から
1900 を引いたものです。

ところで上記のスクリプト、フォームから入力された日付を年月日に分解する処理がないようですが。

# - で分解。
($reg_year, $reg_mon, $reg_day) = split /-/, $FORM{reg_date};
($visit_year, $visit_mon, $visit_day) = split /-/, $FORM{visit_date};

# 年から 1900 を引く。月から 1 を引く。
$reg_year -= 1900;
$reg_mon --;
$visit_year -= 1900;
$visit_mon --;

# 秒数に変換
$reg_time = timelocal(0, 0, 0, $reg_day, $reg_mon, $reg_year);
$visit_time = timelocal(0, 0, 0, $visit_day, $visit_mon, $visit_year);

if($visit_time < $reg_time + 60 * 60 * 24 * 3){

# 3日以内

}


timelocal に存在しない日付を入力すると例外が返るので、
eval ブロックでくくってトラップしてやるか、timelocal に食わせる前に
ちゃんとした数値が入っているかどうかチェックしましょう。


9:[関連] 雅 [2002/05/06 16:55 ]

>>5
Date::Calc とか。


10:[回答] ふじ [URL] [2002/05/07 05:02 ]

>>9
> Date::Calc とか。
Date::Calc は標準モジュールじゃないので、入ってない環境が多そうですし。
XS を使っているので、.pm ファイルだけサーバにアップロードすれば
使える、というものでもないので、Time::Local を使う方法を書いたのですが。

Date::Calc を使うなら、

use Date::Calc qw(Delta_Days);

if(Delta_Days($reg_year, $reg_mon, $reg_day,
             $visit_year, $visit_mon, $visit_day) <= 3){
# 3日以内
}

みたいに簡単に書けますね。

http://bulknews.net/lib/mailmag/31/mag.txt


11:[質問] アブサミラノ [2002/05/08 17:46 ]

ふじさんへ
間が空いてしまいました。ご回答ありがとうございます。
splitなどの意味を調べていたらだいぶ勉強になりました。

教えて頂いた秒数に変換 の処理を施すと、私の書いているスクリプトではエラーが出てしまいます。

以下は私が書いているスクリプトです。

#!/usr/bin/perl

require './jcode.pl';
require './cgi-lib.pl';

&ReadParse(*FORM);
$reg = $FORM{'reg'};
$visit = $FORM{'visit'};
&jcode'convert(*reg, 'sjis');
&jcode'convert(*visit, 'sjis');

use Time::Local;

# - で分解。
($reg_year, $reg_mon, $reg_day) = split /-/, $FORM{reg};
($visit_year, $visit_mon, $visit_day) = split /-/, $FORM{visit};

# 年から 1900 を引く。月から 1 を引く。
$reg_year -= 1900;
$reg_mon --;
$visit_year -= 1900;
$visit_mon --;

# このあたりに秒数に変換する処理および
# 3日以内ならエラーを出す処理を入れていました。

print "Content-type: text/html\n\n";
print <<HTML1;
    <HTML>
    <HEAD>
        <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
        <TITLE>フォームテストCGI</TITLE>
    </HEAD>
    <BODY>
    <FONT SIZE="+2">フォームテストCGI</FONT><BR>
    <BR>
        申込日:$reg<BR>
        訪問予定日:$visit<BR>
    </BODY>
    </HTML>
HTML1

ここまで
ちなみに、htmlのフォームのnameに「reg_time」cgiで
「$reg_time」とするとエラーが出ましたので、「reg」、「$reg」としました。
アドバイスありましたら書き込みをお願いしますm(_ _)m


12:[回答] R.M [2002/05/09 03:56 ]

($reg_year, $reg_mon, $reg_day) = split /-/, $FORM{reg};
($visit_year, $visit_mon, $visit_day) = split /-/, $FORM{visit};

これが

($reg_year, $reg_mon, $reg_day) = split /\//, $FORM{reg};
($visit_year, $visit_mon, $visit_day) = split /\//, $FORM{visit};

こうではないかと思います。

ちなみに
&jcode'convert(*reg, 'sjis');
&jcode'convert(*visit, 'sjis');
この処理は不要かと


13:[回答] アブサミラノ [2002/05/09 13:12 ]

RMさん
( split /\//, $FORM{reg};
は、「/」で分解の意味になりますよね?
ありがとうございます。

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]

ChaichanPAPA's World