PHPで日付をまたいだ時の時間のプルダウン


お店の時間が仮に18:00から翌朝5:00で予約を取るフローで、

※$_POST["open"]は18 $_POST["close"]は05と入るとして

<?php for($j=$_POST["open"]; $j<=$_POST["close"]; $j++){ ?>
<option value="<?php echo $j; ?>"><?php echo $j;?>
</option>
<?php } ?>

この形だと明らかに無理ですよね。ちなみに必ず18:00から翌朝5:00と入るとは限らないのです。
前のページでPostした内容に合わせてプルダウンを変更したいのですが、日付をまたいだときの時間のプルダウンってどうしたら効率よくできるでしょうか??

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2010/11/05 14:25:02
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:tukihatu No.1

回答回数180ベストアンサー獲得回数32

ポイント60pt

そうですね、無理ですね。

そういう場合は普通、18~5ではなくて18~29とします。

※$_POST["open"]は18 $_POST["close"]は05と入るとして

<?php 
$_POST["open"] = 18;
$_POST["close"] = 5;//文字列"05"が入ってくる場合は数値に変換が必要!

if($_POST["open"] > $_POST["close"]){//open時間がclose時間より大きいとき
$_POST["close"] = $_POST["close"]+24;
}

for($j=$_POST["open"]; $j<=$_POST["close"]; $j++){
?>
<option value="<?php echo $j; ?>"><?php echo $j;?>
</option>
<?php } ?>

上の例だとリストには18~29の数字が表示されます。

しかし、05と表示させたいこともあるかと思います。

その場合はこんな感じ

<?php 
$_POST["open"] = 18;
$_POST["close"] = 5;//文字列"05"が入ってくる場合は数値に変換が必要!

if($_POST["open"] > $_POST["close"]){//open時間がclose時間より大きいとき
$_POST["close"] = $_POST["close"]+24;
}

for($j=$_POST["open"]; $j<=$_POST["close"]; $j++){
if($j >= 24){//24時間を越えたら
var $k = $j-24;
if($k < 10){//一桁なら頭に0を追加
$k = "0".$k;
}
}else{//超えてないなら
var $k = $j;
}
?>
<option value="<?php
echo $j;//とりあえずvalueは24超えていてもそのまま(やりやすいほうで)
?>"><?php echo $k;?>
</option>
<?php } ?>

id:goodbabies

ありがとうございます!うまくいきました!

>そういう場合は普通、18~5ではなくて18~29とします。

この考え方は無かったです、勉強になりました。

2010/10/29 15:19:52
id:windofjuly No.2

回答回数2625ベストアンサー獲得回数1149

ポイント10pt

引き続き回答を受け付けておられたので変形しました

 

【改良点1】開始時刻と終了時刻から時差を算出してループに用いてます

【改良点2】終了時刻が開始時刻より大きいか小さいかの違いはifではなく三項演算子で判定してます

三項演算子のメリットは1行で処理が済むこと

今回の場合のデメリットは演算が必ず発生すること

【改良点3】if判定ではなく%演算子で余りを計算するようにしています

こちらも演算が発生するというデメリットがあります

【改良点4】phpが数値と数字をあいまい処理してくれる事に頼らずフォーマットで対処しています

整形の動作コストはかかりますが見た目でハッキリとわかりるため、あいまいさを回避でき、バグを未然に防げます

【放置点】回答1同様に$_POST["open"]並びに$_POST["close"]の値が正しい範囲内のものかどうかの判定はしておりませんので、別途対応が必要

<?php
$c = $_POST["close"] - $_POST["open"] + ( $_POST["open"] > $_POST["close"] ? 24 : 0 );
for( $i = 0; $i <= $c; $i++ ) {
    $k = ( $_POST["open"] + $i ) % 24;
    echo sprintf( "<option value=\"%02d\">%02d</option>" , $k, $k);
}
?>

上記を質問文にあわせて変形すると下記のような具合ですがphpをタグの間にはさみこむと判読性が悪くなり、

記述時や修正時のミスも増えますのでHTML部分とphpスクリプト部分はハッキリ区分けすることも考えたほうが良いかもしれません

(もちろん、そちらの状況によりますから、対応できる範囲で考えてみてください)

<?php $c = $_POST["close"] - $_POST["open"] + ( $_POST["open"] > $_POST["close"] ? 24 : 0 );?>
<?php for( $i = 0; $i <= $c; $i++ ) {?>
<option value="<?php $k = ( $_POST["open"] + $i ) % 24; echo sprintf('%02d', $k); ?>"><?php echo sprintf('%02d', $k);?></option>
<?php } ?>

 

今回は不要かもしれませんが

回答1の「一桁なら頭に0を追加」を下記の場所に移せば

9:00-10:00という予約なども対応できて便利かもしれません

<?php
for($j=$_POST["open"]; $j<=$_POST["close"]; $j++){
if($j >= 24){//24時間を越えたら
    $k = $j-24;
}else{//超えてないなら
    $k = $j;
}
if($k < 10){//一桁なら頭に0を追加
    $k = "0".$k;
}

質問者が未読の回答一覧

 回答者回答受取ベストアンサー回答時間
1 type-a 516 420 40 2010-10-29 23:20:01

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません