iT邦幫忙

0

PHP 月曆假日標註

各位大大好:
我用版友code修改,想請問周六與周日顏色要怎麼與平日顏色不同,大致上我修改了,但3、6、9、12月的最後一周,會產生問題,我是用星期幾(0~6)去判別,但是最後一周會連續跑出3個4
無法接續4、5、6想請問是甚麼問題? 謝謝
大概是以下的標註"顯示42格的$x有問題">"<

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>日曆</title>
</head>

<body>

<?php
 
    function getthemonth($date)
    {
        $firstday = date('Y-m-01', strtotime($date));//取得該日期月份的第一天,PHP內建date時間函數
        $lastday = date('Y-m-d', strtotime("$firstday +1 month -1 day"));//取得該日期月份的最後一天,加一個月減一天
        $month=date('m', strtotime($date));
        $year=date('Y', strtotime($date));
        return array($firstday,$lastday,$month,$year);
    }

    $YM = (isset($_GET['date'])?$_GET['date']:date("Y-m"));//尋找判斷變數是不是有存在,如果有就回傳1 if else的簡寫
    $day=getthemonth($YM);       
    echo '<b>'.$YM.'</b>';
    echo '<br/>';
    echo '這個月有幾 '.$dayCount = date("t",strtotime($day[0])).' 天'; //t直接輸出當月天數;
    echo '<br/>';
    echo '這個月的第一天是禮拜 '.$weekday  = date('w', strtotime($day[0])); //w數字型的星期幾 D英文型的星期幾
    echo '<br/>';
    echo '這個月的最後一天是禮拜 '.date('w', strtotime($day[1]));
    echo '<br/>';
    echo $d_first=date("j",strtotime($day[0])).' - '.$d_last=date("j",strtotime($day[1])); //格式化為以天統計的數字日,不補零
    $d_last=$dayCount+$weekday-1;//若第一天不是禮拜日 
    echo '<br/>';
    echo 'last:'.$d_last."<br>";

?>
<div class="table text" style="width:859px;background-color:#AAAAAA;">

<?php
    
    function changeday($x){
     
    switch ($x)
    
    {
    	case '0':    	
    	return "星期日";    	
    	case '1':    	
    	return  "星期一";    
    	case '2':
    	return  "星期二";   	
    	case '3':
       	return  "星期三";
    	case '4':
    	return "星期四";  	
    	case '5':    	
    	return  "星期五";   	
    	case '6':
    	return  "星期六";
    	
}}

    for($x=0;$x<=6;$x++){//週一到週日
    echo '<div style="background-color:'.($x==0||$x==6 ?'#FF88C2':'#DDDDDD').';width:120.6px;height:30px;float:left; border:#FFFFFF 1px solid;">'
         .changeday($x).  '</div>';       
}
?>
</div>

應該是以下的$x 造成3、6、9月的最後一周周六日會有問題..

<div class="table" style="width:859px;background-color:#333;">
<?php
    
    $i=1;
    for($x=0;$x<=41;$x++){//顯示42格,如果遇六日的欄位與平常日的欄位顏色不同
    echo '<div style="background-color:'.($x+1>$weekday && $x<=$d_last?date('w',strtotime(date("Y-m-$x")))==0||date('w',strtotime(date("Y-m-$x")))==6?'#F0E68C':'#F5DEB3':'#DDDDDD').';width:120.6px;height:160px;float:left; border:#FFFFFF 1px solid;">'.($x+1>$weekday && $x<=$d_last ?'['.$i.']'.date('w',strtotime(date("Y-m-$x"))):'')."</div>";$i=($x+1>$weekday?$i+1:1);
     }
?>
</div>
</table>
<div class="table" style="clear:both;width:890px;">
<a href="?date=<?php echo date("Y-m",strtotime('-1 month',strtotime($YM)));?>" style="float:left;">上個月</a>
<a href="?date=<?php echo date("Y-m",strtotime('+1 month',strtotime($YM)));?>" style="float:right;">下個月</a>
</div>
</body>
</html>
看更多先前的討論...收起先前的討論...
mayyola iT邦新手 4 級 ‧ 2018-01-17 14:52:58 檢舉
修改在上面了,sorry><
weiclin iT邦高手 5 級 ‧ 2018-01-17 15:10:42 檢舉
好長呢..不編輯一下文章用程式碼區塊嗎
我覺得………你可能考慮一下……邏輯和視圖分離……
你上次問的問題我給你範例code……
就算看不懂有沒有試著跑跑看,看會跑出啥東東?
那是很重要的樣板觀念。
程式不是一種從頭硬幹到尾的東西。
你要將功能抽出來設計。
本來想幫他…卻發現討論區不能放markdown code?
測試:
```
Markdown
```
不能Markdown..
幹嘛不直接下面回答就好了~~0..0
weiclin iT邦高手 5 級 ‧ 2018-01-17 16:35:02 檢舉
因為被我搶先回答了 xD
mayyola iT邦新手 4 級 ‧ 2018-01-17 17:43:08 檢舉
Samと可樂快跑 我有看但是看不懂..所以還沒跑>"<拍謝
謝謝分享~~~~
我沒有要回答啦!是weiclin說code沒用程式碼區塊,我想說幫他上一下區塊XD
而且我如果真的要回答,他的code會被我整個大改造的說…
mayyola
我還是建議你先把我上次寫的範例跑跑看。
多少理解一下把程式跟畫面分開的做法。
mayyola iT邦新手 4 級 ‧ 2018-01-17 20:57:27 檢舉
好的,我想問那是三個程式貼成一個php嗎?我真的有點不太懂,謝謝
三個程式是分別不同的三個檔案
一個是樣板功能引入檔
一個是主程式
一個是樣板檔

我不是都有在說明旁邊標上檔名嗎?
注意一下:
view.php 是我寫的功能,你可以假想是第三方程式碼或是元件庫
未來你漸漸會看到很多這種東西。用class包起來的。
這一類的東西主要都不是要你去研究內容。
而是只要知道他「如何使用」就好了。
你真正要看的是主程式如何取用這個view元件,然後讓你的「樣板檔」可以被載入主程式,最後再顯示出結果。

2 個回答

0
weiclin
iT邦高手 5 級 ‧ 2018-01-17 16:25:22
最佳解答

看不懂你在寫什麼, 所以我重寫了一部分
要改的地方一個個點出來太累了
自己看吧, 不明白就在底下提問題

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<style type="text/css">
    .table {
        margin-left: auto;
        margin-right: auto;

    }

    .text {

        text-align: center;
        font-size: 18px;
        font-family: Microsoft JhengHei;
    }
</style>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
    <title>教室借用登記表</title>
</head>

<body>

<?php

function getCalendarData($date)
{
    $timestamp = strtotime($date);
    $month = date('m', $timestamp);
    $year = date('Y', $timestamp);
    $firstDay = "01";
    $lastDay = date('t', $timestamp);//取得該日期月份的最後一天

    return [
        'firstDay' => $firstDay,
        'lastDay' => $lastDay,
        'month' => $month,
        'year' => $year,
        'firstDayDate' => "{$year}-{$month}-{$firstDay}",
        'lastDayDate' => "{$year}-{$month}-{$lastDay}",
    ];
}

$YM = filter_input(INPUT_GET, 'date') ?: date("Y-m");//尋找判斷變數是不是有存在,如果有就回傳1 if else的簡寫
$calData = getCalendarData($YM);
echo '<b>' . $YM . '</b>';
echo '<br/>';
echo '這個月有 ' . $calData['lastDay'] . ' 天';
echo '<br/>';
echo '這個月的第一天是禮拜 ' . $firstWeekday = date('w', strtotime($calData['firstDayDate'])); //w數字型的星期幾 D英文型的星期幾
echo '<br/>';
echo '這個月的最後一天是禮拜 ' . date('w', strtotime($calData['lastDayDate']));
echo '<br/>';
echo "{$calData['firstDay']}-{$calData['lastDay']}";
$lastGridNumber = $calData['lastDay'] + $firstWeekday - 1;//若第一天不是禮拜日
echo '<br/>';
echo 'last:' . $lastGridNumber . "<br>";

?>

<div class="table text" style="width:858px;background-color:#FFE4E1;height:30px;">

    <?php
    echo '<div border:#af9ace 1px solid;>' . $calData['year'] . '年</div>';
    ?>

</div>


<div class="table text" style="width:858px;background-color:#AAAAAA;">

    <?php
    function translateMonth($m)
    {

        $map = ['01' => '一月', '02' => '二月', '03' => '三月', '04' => '四月'
            , '05' => '五月', '06' => '六月', '07' => '七月', '08' => '八月', '09' => '九月', '10' => '十月', '11' => '十一月', '12' => '十二月'];

        return $map[$m];

    }

    echo '<div style="background-color:	#DDDDDD;border:#FFFFFF 1px solid;">' . translateMonth($calData['month']) . '</div>';
    ?>

</div>


<div class="table text" style="width:859px;background-color:#AAAAAA;">

    <?php

    function translateDay($x)
    {
        switch ($x) {
            case '0':
                return "星期日";
            case '1':
                return "星期一";
            case '2':
                return "星期二";
            case '3':
                return "星期三";
            case '4':
                return "星期四";
            case '5':
                return "星期五";
            case '6':
                return "星期六";
        }
    }

    for ($x = 0; $x <= 6; $x++) {//週一到週日
        $color = ($x == 0 || $x == 6 ? '#FF88C2' : '#DDDDDD');
        ?>
        <div style="background-color:<?= $color ?>;width:120.6px;height:30px;float:left; border:#FFFFFF 1px solid;">
            <?= translateDay($x) ?>
        </div>
        <?php
    }
    ?>
</div>
<div class="table" style="width:859px;background-color:#333;">
    <?php
    $colorOfOutRange = '#DDDDDD';
    $colorOfWeekday = '#F5DEB3';
    $colorOfWeekend = '#F0E68C';

    $day = 1;
    for ($x = 0; $x <= 41; $x++) {//顯示42格
        if ($x < $firstWeekday || $x > $lastGridNumber) {
            // out of range
            echo '<div style="background-color:' . $colorOfOutRange . ';width:120.6px;height:160px;float:left; border:#FFFFFF 1px solid;"></div>';
        } else {
            // current month
            $dayOfWeek = ($x % 7);
            $color = in_array($dayOfWeek, [0, 6]) ? $colorOfWeekend : $colorOfWeekday;
            echo '<div style="background-color:' . $color . ';width:120.6px;height:160px;float:left; border:#FFFFFF 1px solid;">'
                . "[$day]" . $dayOfWeek
                . '</div>';
            ++$day;
        }
    }
    ?>
</div>
<div class="table" style="clear:both;width:890px;">
    <a href="?date=<?= date("Y-m", strtotime('-1 month', strtotime($YM))); ?>" style="float:left;">上個月</a>
    <a href="?date=<?= date("Y-m", strtotime('+1 month', strtotime($YM))); ?>" style="float:right;">下個月</a>
</div>
</body>
</html>
看更多先前的回應...收起先前的回應...
mayyola iT邦新手 4 級 ‧ 2018-01-17 17:42:32 檢舉

w大您好,我想請問$lastGridNumber = $calData['lastDay'] + $firstWeekday - 1是什麼意思 謝謝!!

weiclin iT邦高手 5 級 ‧ 2018-01-17 17:56:04 檢舉

那一行是你寫的啊...我只有把變數名稱換掉
我理解應該是計算這個月最後一天是在第幾格
因為我是隨手改一改, 如果有弄錯的話跟我講一下

mayyola iT邦新手 4 級 ‧ 2018-01-18 14:22:18 檢舉

w大您好:
想再請問
in_array($dayOfweek,[0,6]) 如果再陣列$dayOfweek找到餘數為0跟6就是true嗎?
因為我找到的方式好像是到反過來- -?這有差嗎?

<?php
$sites = array("Google", "Runoob", "Taobao", "Facebook");
 
if (in_array("Runoob", $sites))
{
    echo "找到匹配项!";
}
else
{
    echo "没有找到匹配项!";
}
?>
weiclin iT邦高手 5 級 ‧ 2018-01-18 14:27:27 檢舉

那行用白話文來說就是: 如果 $dayOfWeek 是 [0, 6] 其中之一的話
所以 $dayOfWeek 是 0 或 6 的時候是 true

要用來比對很多個數值的時候很好用, 可以少打很多字
不然你比對三個就要寫成 $a == 0 || $a == 1 || $a == 2
in_array 就是 in_array($a, [0, 1, 2])

0
Samと可樂快跑
iT邦研究生 3 級 ‧ 2018-01-17 20:03:30

好吧!反正我得了看到很混亂的code不整理就會死的病………(那我怎麼還活著?)
基本上……該運算的該指定的該幹嘛的一開始就先做好。
到了html的地方就只是呈現上去而已。
我時間不夠多就隨便亂做。
事實上還有很多該改的地方就是了。
(可惡!為了markdown只好回答了。)

<?php
$YM = (isset($_GET['date'])?$_GET['date']:date("Y-m"));//尋找判斷變數是不是有存在,如果有就回傳1 if else的簡寫
$day=getthemonth($YM);
$dayCount = date("t",strtotime($day[0]));
$weekday = date('w', strtotime($day[0]));
$d_first = date("j",strtotime($day[0])).' - '.$d_last=date("j",strtotime($day[1]));
$d_last = $dayCount+$weekday-1;

function getthemonth($date)
{
    $firstday = date('Y-m-01', strtotime($date));//取得該日期月份的第一天,PHP內建date時間函數
    $lastday = date('Y-m-d', strtotime("$firstday +1 month -1 day"));//取得該日期月份的最後一天,加一個月減一天
    $month=date('m', strtotime($date));
    $year=date('Y', strtotime($date));
    return array($firstday,$lastday,$month,$year);
}

function changeday($x){

    return '星期' . ['日','一','二','三','四','五','六'][$x];

}

function bgColor($x , $weekday , $d_last) {

    if ($x+1 <= $weekday || $x > $d_last) {
        return '#DDDDDD';
    }

    if (in_array($x % 7 ,[0,6])) {
        return '#F0E68C';
    }

    return '#F5DEB3';

}
?>

<!DOCTYPE HTML>
<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
    <title>日曆</title>
</head>

<body>

<b><?=$YM?></b> <br>
這個月有幾 <?=$dayCount?> 天 <br>

這個月的第一天是禮拜 <?=$weekday?> <br>

這個月的最後一天是禮拜 <?=date('w', strtotime($day[1]))?> <br>

last:<?=$d_last?><br>


<div class="table text" style="width:859px;background-color:#AAAAAA;">
    <?php for($x=0;$x<=6;$x++): ?> <!-- 周一到週日 -->
        <div style="background-color:<?= ($x==0||$x==6) ? '#FF88C2' : '#DDDDDD'?>;width:120.6px;height:30px;float:left; border:#FFFFFF 1px solid;">
            <?=changeday($x)?>
        </div>
    <?php endfor?>
</div>

<div class="table" style="width:859px;background-color:#333;">
    <?php $i = 1?>
<?php for($x = 0 ; $x <= 41 ; $x ++):?>
    <div style="background-color:<?=bgColor($x , $weekday , $d_last)?>;width:120.6px;height:160px;float:left; border:#FFFFFF 1px solid;">
        <?=$x+1 > $weekday && $x <= $d_last ? '['.$i.']'.date('w',strtotime(date("Y-m-$x"))):''?>
    </div>

    <?php $i = ($x + 1 > $weekday ? $i + 1 : 1) ?>

<?php endfor?>


</div>

<div class="table" style="clear:both;width:890px;">
    <a href="?date=<?php echo date("Y-m",strtotime('-1 month',strtotime($YM)));?>" style="float:left;">上個月</a>
    <a href="?date=<?php echo date("Y-m",strtotime('+1 month',strtotime($YM)));?>" style="float:right;">下個月</a>
</div>
</body>
</html>

看更多先前的回應...收起先前的回應...
weiclin iT邦高手 5 級 ‧ 2018-01-17 20:05:10 檢舉

改到他媽媽都認不出來了
/images/emoticon/emoticon37.gif

還可以有這種操作:

這個月的第一天是<?=changeday($weekday)?> <br>

這個月的最後一天是<?=changeday(date('w',strtotime($day[1])))?> <br>

weiclin可是他不學習這樣整理的話………
後面問題更多………

weiclin iT邦高手 5 級 ‧ 2018-01-17 20:21:27 檢舉

因為還是新手而已, 預計至少還要一兩個月才能體會這種寫法好處吧

mayyola iT邦新手 4 級 ‧ 2018-01-18 11:38:16 檢舉

Samと可樂快跑您好:
我想請問以下是陣列的用法嗎?我有上網找..都找不到語法的格式
星期'.['日','一','二','三','四','五','六'][$x]
想再請問

<?=changeday($weekday)?> "<?= ?>"=>

這是甚麼用法呢? 謝謝
因為我只看過

<?php ?>、<? ?>

這個語法是php 5.4後支援,所以如果你php版本太舊就不行。
(但現在沒有裝個5.6或是php 7很奇怪吧……)
簡單來說,我省略了變數去接陣列。
所以['日','一','二','三','四','五','六']就是個陣列本體。然後直接用[$x]取出陣列索引的值。
如果你要的是標準寫法:

//其實函式名稱還是用駝峰式寫法來統一比較好
function changeDay($x) {
    $weeks = array('日','一','二','三','四','五','六');
    return '星期' . $weeks[$x];
}

喵的!swift寫久了常常都忘了要加「;」

mayyola iT邦新手 4 級 ‧ 2018-01-18 12:08:23 檢舉

謝謝 可是我上網找怎麼都找不到這種用法,囧 這要怎麼搜尋

PHP Manual array
或Google關鍵字:
php array 簡寫

weiclin iT邦高手 5 級 ‧ 2018-01-18 13:41:43 檢舉
<?=$var?>

其實就是

<?php echo $var?>

的簡式寫法
但是要注意的是,php.ini如果沒有把 short_open_tag 打開的話
就沒辦法使用。
(但是有些framework會做強制打開的設定或是做轉換功能)

weiclin iT邦高手 5 級 ‧ 2018-01-18 14:28:26 檢舉

那個在 php 5.4 以後不管有沒有開 short_open_tag 都可以用了喔

mayyola iT邦新手 4 級 ‧ 2018-01-18 18:23:33 檢舉

我想再請問兩位,剛看網路上的農曆語法非常複雜(看都看不懂),那是要跟國曆寫在一起嗎?(想說把放假日也標註在日曆上,國曆是標好了但剩農曆跟彈性放假日= =)謝謝

weiclin iT邦高手 5 級 ‧ 2018-01-18 21:14:03 檢舉

農曆不好弄喔, 或許參考每年公佈的行事曆來標示比較快
http://www.319papago.idv.tw/holiday/2018-hr/2018_HR.html

我要發表回答

立即登入回答