收藏本站腾讯微博新浪微博

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 网站开通淘帖功能 - 蓝色理想插件 论坛内容导读一页看论坛 - 给官方提建议

论坛活动及任务 地图和邮件任务 请多用悬赏提问 热夏来袭,选一款蓝色理想的个性T恤吧!

手机上论坛,使用APP获得更好体验 急需前端攻城狮,获得内部推荐机会 论坛开通淘帖功能,收藏终于可以分类了!

搜索
查看: 8357|回复: 10

[php] php练习代码-日历

[复制链接]
发表于 2007-12-8 16:59:09 | 显示全部楼层 |阅读模式
+效果
calendar.PNG

+无题
这次给自己的练习是写个日历的代码
开始以为很简单,到后来写着写着自己都晕了。
我的思路是来自学习C语言的一个练习题
那个练习题是要求在屏幕打印出如图所示图形:
        *      
      ***      
     *****      
    *******      


思路是:获取每月第一天和最后一天是星期几,用FOR循环输出,其他的也用FOR循环输出。

虽然我写出来了,但是感觉比较繁琐,而且可读性不强,PHP函数库的丰富没有体现出来。
我想还有改进的空间,大家来指点指点吧。

+代码

  1. <?
  2. $y=$_GET['y'];
  3. $m=$_GET['m'];

  4. function calendar($y,$m){

  5. $months=array('January','February','March','April','May','June','July','August','September','October','November','December');
  6. $days=array('31','28','31','30','31','30','31','31','30','31','30','31');

  7.         if($y==$today['year']&&$m==$today['mon'])
  8.         {
  9.                 $today=getdate();
  10.         }
  11.         else
  12.         {
  13.                 $date="1 ".$months[$m-1]." ".$y;
  14.                 $today=getdate(strtotime($date));
  15.         }
  16. //print_r($today);
  17. $wd=$today['wday'];
  18. $md=$today['mday'];
  19. $m=$m?$m:$today['mon'];
  20. $y=$y?$y:$today['year'];


  21. if(!($y%4))
  22. {$days[1]=29;}

  23. if($md<=7)
  24.    {
  25.             $mfd=$wd-($md-1);
  26.         $mfd=$mfd>0?$mfd:($mfd+7);
  27.    }
  28.    else
  29.    {
  30.            $mfd=(8-($md-$wd)%7)%7;
  31.     }
  32. $mld=($days[$m-1]-(8-$mfd))%7;
  33. $mld=$mld?$mld:7;
  34. $plusweek=($mld+7)%7?2:1;
  35. $weeks=($days[$m-1]-(8-$mfd)-$mld)/7+$plusweek;
  36. $forarray=array();
  37. array_push($forarray,$mfd."7");
  38. if($mld==7)
  39.         {
  40.         $lines=$weeks-1;
  41.         }
  42. else
  43.         {
  44. $lines=$weeks-2;
  45.         }
  46.         for($i=0;$i<$lines;$i++)
  47. {array_push($forarray,"17");}
  48. array_push($forarray,"1".$mld);
  49. $ms=1;

  50. if($m==1)
  51.         {
  52.         $prey=$y-1;
  53.     $prem=12;
  54.         $nexy=$y;
  55.     $nexm=(12+($m+1))%12;
  56.         $nexm=$nexm?$nexm:0;
  57.     }
  58. else if($m>1&&$m<12)
  59.         {
  60.                 $nexy=$prey=$y;
  61.                 $prem=(12+($m-1))%12;
  62.                 $prem=$prem?$prem:12;
  63.                 $nexm=(12+($m+1))%12;
  64.                 $nexm=$nexm?$nexm:0;
  65.         }
  66. else
  67.         {
  68.         $prey=$y;
  69.         $prem=(12+($m-1))%12;
  70.         $prem=$prem?$prem:12;
  71.         $nexy=$y+1;
  72.     $nexm=1;
  73.         }

  74. echo "<table>\n<thead><tr><th colspan='1'><a href='?y={$prey}&m={$prem}'>-</a></th><th colspan='5'> {$y} {$months[$m-1]} </th><th colspan='1'><a href='?y={$nexy}&m={$nexm}'>+</a></th></tr><thead>\n<tbody><tr><td>一</td><td>二</td><td>三</td><td>四</td><td>五</td><td>六</td><td>日</td></tr>";
  75. for($i=0;$i<count($forarray);$i++)
  76. {
  77.         $s=substr($forarray[$i],0,1);
  78.         $e=substr($forarray[$i],1,2);
  79.         echo "<tr>";
  80.         for($j=1;$j<=$e;$j++)
  81.         {
  82.                 if($j<$s)
  83.                 {echo "<td></td>";}
  84.                 else
  85.                 {echo "<td>{$ms}</td>";
  86.                 $ms++;}
  87.         }
  88.         echo "</tr>\n";
  89. }
  90. //echo "</tbody></table>";
  91. //echo "{$m}月第一天是星期{$mfd}<br />";
  92. //echo "{$m}月最后一天是星期{$mld}<br />";
  93. //echo "{$m}月跨度{$weeks}周".count($forarray);
  94. //print_r($forarray);
  95. }
  96. calendar($y,$m);
  97. ?>
复制代码
发表于 2007-12-8 20:17:06 | 显示全部楼层
这是我写的,欢迎指正
  1. $m=isset($_GET['m'])?$_GET['m']:date('n');
  2. $y=isset($_GET['y'])?$_GET['y']:date('Y');
  3. function calendar($m,$y){
  4.         $mtime=mktime(0,0,0,$m,1,$y);
  5.         $f=date('w',$mtime)-1;
  6.         $s='<table border="0" cellpadding="2" cellspacing="1"><tr><td colspan="7"><a href="?m='.$m.'&amp;y='.(intval($y)<=1971?'1971':intval($y)-1).'">&lt;&lt;</a>&nbsp;&nbsp;<a href="?m='.(intval($m)==1?'12':intval($m)-1).'&amp;y='.(intval($m)==1?(intval($y)-1):intval($y)).'">&lt;</a> '.intval($m).'/'.$y.' <a href="?m='.(intval($m)==12?'1':intval($m)+1).'&amp;y='.(intval($m)==12?(intval($y)+1):intval($y)).'">&gt;</a>&nbsp;&nbsp;<a href="?m='.$m.'&y='.(intval($y)>=2037?'2037':intval($y)+1).'">&gt;&gt;</a></td></tr><tr><td>日</td><td>一</td><td>二</td><td>三</td><td>四</td><td>五</td><td>六</td></tr>';
  7.         for($i=0;$i<date('t',$mtime)+$f+1;$i++){
  8.                 if($i%7==0)$s.='<tr>';
  9.                 $s.='<td>';
  10.                 if($i>$f)$s.=$i-$f;
  11.                 $s.='</td>';
  12.                 if($i%7==6)$s.='</tr>';
  13.         }
  14.         if($i%7<6 && $i%7>0)$s.='<td colspan="'.(7-$i%7).'"></td></tr>';
  15.         if($i%7==6)$s.='<td></td></tr>';
  16.         return $s.'</table>';
  17. }
  18. echo calendar($m,$y);
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-12-9 10:59:09 | 显示全部楼层
  piscdong 的代码简炼不少啊!
后面的同学们,继续来。
回复 支持 反对

使用道具 举报

发表于 2007-12-9 11:43:54 | 显示全部楼层
君子生非异也,善假于物也
用pear里的Calendar包
http://pear.php.net/package/Calendar/download


  1. <?php
  2. require_once('Calendar/Month/Weekdays.php');
  3. $year  = date("Y");
  4. $month = date("m");
  5. $monthCalendar = new Calendar_Month_Weekdays($year, $month, 0);
  6. $monthCalendar->build();

  7. echo "<table >\n";
  8. echo "        <tr><td colspan='7' style='text-align:center'>$year, $month</td></tr>\n";
  9. echo "        <tr><td>日</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td>\n";
  10. while ($day = $monthCalendar->fetch())
  11. {
  12.         if($day->isFirst())       
  13.         {
  14.                 echo "        <tr>";
  15.         }
  16.        
  17.         if($day->isEmpty())
  18.         {
  19.                 echo "<td>&nbsp;</td>";
  20.         }
  21.         else
  22.         {
  23.                 echo "<td>".$day->thisDay()."</td>";
  24.         }
  25.         if($day->isLast())
  26.         {
  27.                 echo "</tr>\n";
  28.         }
  29. }
  30. echo "</table>";


  31. ?>
复制代码


BTW,PHP5里面还有个Date类,有空再用那个试试

[[i] 本帖最后由 Fanbin 于 2007-12-9 11:45 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2007-12-9 14:46:02 | 显示全部楼层
我也来献个丑。方法跟你的差不多,也是初学的时候写的。



  1. function getdata ($month="",$year="") {

  2. if (!$month) $month = date("n");
  3. if (!$year) $year = date("Y");

  4. $weekday_cn = array("日","一","二","三","四","五","六");

  5. if ($month !=2) {
  6.    switch ($month) {
  7.    case 1:
  8.        $day = 31;
  9.            break;
  10.    case 3:
  11.        $day = 31;
  12.            break;
  13.     case 4:
  14.            $day = 30;
  15.            break;
  16.         case 5:
  17.            $day = 31;
  18.            break;
  19.         case 6:
  20.            $day = 30;
  21.            break;
  22.         case 7:
  23.            $day = 31;
  24.            break;
  25.         case 8:
  26.            $day = 31;
  27.            break;
  28.         case 9:
  29.            $day = 30;
  30.            break;
  31.         case 10:
  32.            $day = 31;
  33.            break;
  34.         case 11:
  35.            $day = 30;
  36.            break;
  37.         case 12:
  38.            $day = 31;
  39.            break;
  40.        }
  41.          }else{
  42.          if (date('L',mktime(0,0,0,$month,0,$year))) {
  43.              $day = 29;
  44.                  }else{
  45.                  $day = 28;
  46.                  }
  47.         }
  48.                  
  49. $start_day = (int)date("w",mktime(0,0,0,$month,date("j",mktime(0,0,0,$month,1,$year)),$year));

  50. $n=1;

  51. $today=(int)date("j");
  52. ob_start ();
  53. echo "<table width=\"200\" border=\"0\" cellspacing=\"1\" cellpadding=\"2\" bgcolor=\"#CCCCCC\"><tr bgcolor=\"#FFFFFF\">";

  54. echo "<th colspan=\"7\" scope=\"col\">".$year."年".$month."月"."</th></tr>\n";
  55. echo "<tr align=\"center\"  bgcolor=\"#CCFFCC\">";
  56. for ($i=0;$i<count($weekday_cn);$i++) {
  57.     echo "<th scope=\"col\">".$weekday_cn[$i]."</th>\n";
  58.     }
  59.         echo "</tr>";
  60.        
  61. //ӡһ
  62. echo "<tr align=\"center\" bgcolor=\"#FFFFFF\"> \n";
  63. for ($i=0;$i<$start_day;$i++)
  64. echo "<td> </td>\n";
  65. for ($j=0;$j<(7-$start_day);$j++) {
  66.       $table_td= ($today ==$n)?("<td  bgcolor=\"#006699\"><span style=\"color:#FFFFFF;font-weight: bold;\">".$n."</span></td>"):("<td>".$n."</td>");
  67.           echo $table_td;
  68.           $n++;
  69.           }
  70. echo "</tr>\n";

  71. $m=($n-1);

  72. for($i=0;$i<(ceil($day-$m)/7);$i++){

  73.   echo "<tr align=\"center\" bgcolor=\"#FFFFFF\"> ";

  74.        for ($j=0;$j<7;$j++) {
  75.              if ($n<=$day) {
  76.                      $table_td= ($today ==$n)?("<td bgcolor=\"#006699\"><span style=\"color:#FFFFFF;font-weight: bold;\">".$n."</span></td>"):("<td>".$n."</td>");
  77.                      echo $table_td;
  78.                         $n++;
  79.                 }else{
  80.                        echo "<td> </td>\n";
  81.                        }
  82.                     }
  83.         echo "</tr>";
  84.         }
  85.    
  86. echo "</table>";
  87. return ob_get_flush ();
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-12-9 15:51:09 | 显示全部楼层
------------------------------------------------------------
做这个测试,纯属好玩,没任何其他的意思。
Calendar包懒的装,所以Fanbin的就没测试了
测试文件已打包,大家有兴趣的可以拿去玩玩
------------------------------------------------------------


看到大家都很积极,对上面几段代码做了个效率测试
+测试方法
<?
$starttime=microtime();
-------------------------------
日历函数,为了看出效果,重复十遍。
-------------------------------
$endtime=microtime();
$usedtime=$endtime-$starttime;
echo "总计用时:{$usedtime}";
?>
分别存为三文件,测试十遍。
+测试结果
result.PNG
+测试结论:
代码的简洁是要付出效率的代价(个人意见)。

test.rar

2.62 KB, 下载次数: 372

测试文件打包

回复 支持 反对

使用道具 举报

发表于 2007-12-9 17:01:43 | 显示全部楼层
咦,没尝试Pear包的啊?
回复 支持 反对

使用道具 举报

发表于 2007-12-9 17:13:46 | 显示全部楼层
不用测,我用Pear包的基本上应该是最慢的。
回复 支持 反对

使用道具 举报

发表于 2007-12-12 23:02:23 | 显示全部楼层
楼主预先定义了很多东西,这些根本不用自己去定义的,日期这东西是固定的
date()函数结合mktime() 可以得到一切东西
我觉得灵活运用两者即可得到日历了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-12-20 19:55:50 | 显示全部楼层
感谢楼上的意见
有空再精炼精炼
回复 支持 反对

使用道具 举报

发表于 2007-12-22 12:37:33 | 显示全部楼层
  1. <?php
  2. /**
  3. * 日历
  4. *
  5. * Copyright(c) 2007 by 陈毅鑫(深空). All rights reserved
  6. * To contact the author write to {@link mailto:shenkong@php.net}
  7. * @author 陈毅鑫(深空)
  8. */

  9. if (function_exists('date_default_timezone_set')) {
  10.     date_default_timezone_set('Asia/Chongqing');
  11. }
  12. $date = isset($_GET['date']) ? $_GET['date'] : date('Y-m-d');

  13. $date = getdate(strtotime($date));
  14. $end = getdate(mktime(0, 0, 0, $date['mon'] + 1, 1, $date['year']) - 1);
  15. $start = getdate(mktime(0, 0, 0, $date['mon'], 1, $date['year']));
  16. $pre = date('Y-m-d', $start[0] - 1);
  17. $next = date('Y-m-d', $end[0] + 86400);

  18. $html = '<table border="1">';
  19. $html .= '<tr>';
  20. $html .= '<td><a href="' . $PHP_SELF . '?date=' . $pre . '">-</a></td>';
  21. $html .= '<td colspan="5">' . $date['year'] . ';' . $date['month'] . '</td>';
  22. $html .= '<td><a href="' . $PHP_SELF . '?date=' . $next . '">+</a></td>';
  23. $html .= '</tr>';

  24. $arr_tpl = array(0 => '', 1 => '', 2 => '', 3 => '', 4 => '', 5 => '', 6 => '');
  25. $date_arr = array();
  26. $j = 0;
  27. for ($i = 0; $i < $end['mday']; $i++) {
  28.     if (!isset($date_arr[$j])) {
  29.         $date_arr[$j] = $arr_tpl;
  30.     }
  31.     $date_arr[$j][($i+$start['wday'])%7] = $i+1;
  32.     if ($date_arr[$j][6]) {
  33.         $j++;
  34.     }
  35. }
  36. foreach ($date_arr as $value) {
  37.     $html .= '<tr>';
  38.     foreach ($value as $v) {
  39.         if ($v) {
  40.             if ($v == $date['mday']) {
  41.                 $html .= '<td><b>' . $v . '</b></td>';
  42.             } else {
  43.                 $html .= '<td>' . $v . '</td>';
  44.             }
  45.         } else {
  46.             $html .= '<td>&nbsp;</td>';
  47.         }
  48.     }
  49.     $html .= '</tr>';
  50. }


  51. $html .= '</table>';
  52. echo $html;

  53. ?>
复制代码

抽空写了个,比较简单的^_^

[[i] 本帖最后由 深空 于 2007-12-22 13:05 编辑 ]
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|Archiver|手机版|blueidea.com ( 湘ICP备12001430号 )  

GMT+8, 2020-3-31 06:09 , Processed in 0.148065 second(s), 11 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表