人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

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した内容に合わせてプルダウンを変更したいのですが、日付をまたいだときの時間のプルダウンってどうしたら効率よくできるでしょうか??

●質問者: goodbabies
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:00 open PHP フロー
○ 状態 :終了
└ 回答数 : 2/3件

▽最新の回答へ

1 ● 牛乳先生(tukihatu)
●60ポイント

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

そういう場合は普通、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 } ?>

◎質問者からの返答

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

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

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


2 ● うぃんど
●10ポイント

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

【改良点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;
}
関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ