【问题标题】:Grab all Wednesdays in a given month in PHP在 PHP 中获取给定月份的所有星期三
【发布时间】:2010-11-27 18:22:57
【问题描述】:

这是我正在尝试编写的函数:

function getWednesdays($month, $year) {
   // Returns an array of DateTimes representing all Wednesdays this month.
}

有什么想法吗?谢谢-

【问题讨论】:

标签: php datetime


【解决方案1】:

使用 PHP5.3

function getWednesdays($y, $m)
{
    return new DatePeriod(
        new DateTime("first wednesday of $y-$m"),
        DateInterval::createFromDateString('next wednesday'),
        new DateTime("last day of $y-$m")
    );
}

用法:

foreach (getWednesdays(2010, 11) as $wednesday) {
    echo $wednesday->format("l, Y-m-d\n");
}

输出:

Wednesday, 2010-11-03
Wednesday, 2010-11-10
Wednesday, 2010-11-17
Wednesday, 2010-11-24

请注意,这将不包括结束日期,因此如果 $y-$m 的最后一天恰好是星期三,它将不在列表中。您必须在结束日期中添加一天才能包含它。要包含它,请将结束日期中的相对格式更改为

new DateTime("next month $y-$m-01")

然后将结束日期设置为下个月的第一天,


使用 PHP

function getWednesdays($y, $m)
{
    $ts  = strtotime("first wednesday $y-$m-01");
    $end = strtotime("last wednesday $y-$m");
    $wednesdays = array();
    while($ts <= $end) {
        $wednesdays[] = $ts;
        $ts = strtotime('next wednesday', $ts);
    }
    return $wednesdays;
}

用法:

foreach (getWednesdays(2010, 11) as $wednesday) {
    echo date("l, Y-m-d\n", $wednesday);
}

与上述相同的输出 (Run on Codepad)。

注意这个does not work for any version prior to 5.3是由于相对格式解析器的变化。如果您想在 PHP 5.3+ 中使用它,您必须将 first Wednesday $y-$m-01 更改为 first Wednesday of $y-$m-01(注意“of”)。此外,就像在 DateTime 版本中一样,结束日期将不包括在内。


进一步阅读:

【讨论】:

  • 如果我在 2014 年 1 月的每个星期五返回,我会得到 4 个星期五,不包括当月的最后一天,即星期五。有什么想法吗?
  • @LukeOliff 它不包括结束日期。您必须在其中添加一天以包含它。查看更新。
  • 好的,谢谢。我在这里提出了一个问题:stackoverflow.com/questions/17891477/… 我只需要添加一秒钟,但只用了一分钟以防万一:)
  • 2015年9月(2015,9),上周三不返回,总共有5个星期三,但只返回4个。
  • @15121991 请注意声明 "的段落,注意这将不包括结束日期,因此如果 $y-$m 的最后一天恰好是星期三,它不会在列表。您必须在结束日期中添加一天才能包含它。要包含它,请将结束日期中的相对格式更改为 new DateTime("next month $y-$m-01")"
【解决方案2】:

你可以试试这样的:

function getWednesdays($month, $year) {
    $base_date = strtotime($year . '-' . $month . '-01');
    $wed = strtotime('first wed of ' . date('F Y', $base_date));

    $wednesdays = array();

    do {
        $wednesdays[] = new DateTime(date('r', $wed));
        $wed = strtotime('+7 days', $wed);
    } while (date('m', $wed) == $month);

    return $wednesdays;
}

【讨论】:

    【解决方案3】:

    使用此函数获取一个月内任何天的总计数

        function getTotalDays($year, $month, $day){
            $from = $year."-".$month."-01";
            $t=date("t",strtotime($from));
    
            for($i=1; $i<$t; $i++){
               if( strtolower(date("l",strtotime($year."-".$month."-".$i)))== $day){
                 $count++;
              }
          }
          return $count;
     }
    

    像这样使用 getTotalDays('2014', '08','monday');

    将输出 4

    但是如果你想要一个月中某一天的所有日期,那么使用这个函数

        function getTotalDatesArray($year, $month, $day){
            $date_ar=array();
            $from = $year."-".$month."-01";
            $t=date("t",strtotime($from));
    
            for($i=1; $i<$t; $i++){
               if( strtolower(date("l",strtotime($year."-".$month."-".$i)))== $day){
                $j= $i>9 ? $i: "0".$i;
                 $date_ar[]=$year."-".$month."-".$j;
              }
          }
          return $date_ar;
     }
    

    像这样使用 getTotalDatesArray('2014', '08','monday');

    将输出数组([0] => 2014-08-04 [1] => 2014-08-11 [2] => 2014-08-18 [3] => 2014-08-25)

    【讨论】:

      【解决方案4】:

      可能有一种更有效的方法,但这很有效:

      <?php
      function isWednesday($day, $month, $year)
      {
          if (date('w', $date = mktime(0,0,0,$month,$day,$year)) == 3) {
              return $date;
          }
          return false;
      }
      function getWednesdays($month, $year)
      {
          for ($day=1; $day<=7; $day++) {
              if ($date = isWednesday($day, $month, $year)) {
                  break;
              }
          }
          $wednesdays = array();
      
          while (date('m',$date) == $month) {
              $wednesdays[] = $date;
              $day += 7;
              $date = isWednesday($day, $month, $year);
          }
          return $wednesdays;
      }
      

      你可以用这个来测试:

      foreach (getWednesdays($argv[1], $argv[2]) as $date) {
          echo date("Y-m-d\n", $date);
      }
      
      $ php wednesdays.php 11 2010
      2010-11-03
      2010-11-10
      2010-11-17
      2010-11-24
      $ php wednesdays.php 12 2010
      2010-12-01
      2010-12-08
      2010-12-15
      2010-12-22
      2010-12-29
      $ php wednesdays.php 2 2012
      2012-02-01
      2012-02-08
      2012-02-15
      2012-02-22
      2012-02-29
      

      S

      【讨论】:

        【解决方案5】:
        <?php
        function wednesdays($month, $year)
        {
          list($n,$d) = explode('-', date('t-d', strtotime("Wednesday, $year-$month")));
          $days = array();
          while ($d <= $n)
          {
            $days[] = sprintf("%04d-%02d-%02d", $year, $month, $d);
            $d += 7;
          }
          return $days;
        }
        
        var_dump(wednesdays(11, 2010));
        
        ?>
        

        但我强烈建议您习惯 PHP 5.3 的日期和时间函数(如果可以使用的话)。 (见戈登的回答。)

        【讨论】:

        • 另一个很好的答案,但你是对的,Gordon 正在充分利用 PHP 的现有功能..
        【解决方案6】:

        对于早于 5.3 的 PHP,此解决​​方案不起作用。似乎,第一天时间戳大于最后一天时间戳,最终终止循环。

        由于 PHP 在午夜计算时差,因此当月份从相关日期开始时,此解决方案不起作用。在某些情况下,最后一天也不起作用。

        我在下面的代码中整理了这些问题。此代码可用于一周中的任何一天。

        该解决方案是借助 Eli 在此问题中的代码创建的:Get the First or Last Friday in a Month

        ///// code starts here /////
        
        function getWeekDates($year, $month, $day){
        $tsInMonth = strtotime("$year-$month");
        $monthNumber = (int)date("m",$tsInMonth);
        
        $Names = array( 1=>"Sun", 2=>"Mon", 3=>"Tue", 4=>"Wed", 5=>"Thu", 6=>"Fri", 7=>"Sat" );
        
        $ThisMonthTS = strtotime( date("Y-m-01", $tsInMonth ) );
        $NextMonthTS = strtotime( date("Y-m-01", strtotime("next month", $tsInMonth) ) );
        
        $weekDates = array();
        
        for($Ord=1;$Ord<=5;$Ord++){
            $DateOfInterest = (-1 == $Ord) 
                ? strtotime( "last ".$Names[$day], $NextMonthTS ) 
                : strtotime( $Names[$day]." + ".($Ord-1)." weeks", $ThisMonthTS );
        
            ($Ord==5 && (int)date("m",$DateOfInterest)==(int)date("m",$NextMonthTS))
                ? false
                : $weekDates [] = $DateOfInterest;
        }
        
        return $weekDates;
        }
        
        ///// Usage /////
        
        foreach (getWeekDates("2010", "2", "2") as $day) {
            echo "<br>" . date("l, Y-m-d", $day);
        }
        
        ///// End of code /////
        

        我希望它对某人有所帮助。

        【讨论】:

          【解决方案7】:

          我已经重写了@Gordon 的解决方案以适应任何一天

          function get_dates_of_day($y, $m, $day_name)
          {
              return new DatePeriod(
                  new DateTime("first $day_name of $y-$m"),
                  DateInterval::createFromDateString("next $day_name"),
                  new DateTime("next month $y-$m-01")
                  );
          }
          

          现在你可以简单地做get_dates_of_day('2015','08','wednesday') 并使用它来获取给定月份中任何一天的日期。

          【讨论】:

            【解决方案8】:

            我为此目的编写了以下代码......它对我来说非常适合

            function get_month_date($year, $month, $day) {
            $monthdays = date('t', mktime(0, 0, 0, $month, 1, $year));
            $dates = array();
            for($i = 0; $i <= $monthdays; $i++ ) {
                if($day == date('l', mktime(0, 0, 0, $month, 1+$i, $year)) && $month == date('n', mktime(0, 0, 0, $month, 1+$i, $year))) {
                $dates[] = date('Y-m-d', mktime(0, 0, 0, $month, 1+$i, $year));
                }
            }
            return $dates; }
            

            我们可以把它当作:

            $days = get_month_date($year, $month, 'Wednesday');
            

            它将返回给定月份和年份中星期三的所有日期的数组

            【讨论】:

              【解决方案9】:

              这里是示例

              function getSundays($y,$m){ 
                  $date = "$y-$m-01";
                  $first_day = date('N',strtotime($date));
                  $first_day = 7 - $first_day + 1;
                  $last_day =  date('t',strtotime($date));
                  $days = array();
                  for($i=$first_day; $i<=$last_day; $i=$i+7 ){
                      $days[] = $i;
                  }
                  return  $days;
              }
              
              $days = getSundays(2016,04);
              print_r($days);
              

              【讨论】:

                【解决方案10】:

                试试这个以获得当月的所有星期三。

                $month  = date('m');
                $year  = date('Y');
                function getDays($year,$month){ 
                 $days = cal_days_in_month(CAL_GREGORIAN, $month,$year);
                 $wed = array();
                 for($i = 1; $i<= $days; $i++){
                 $day  = date('Y-m-'.$i);
                 $result = date("D", strtotime($day));
                 if($result == "Wed"){  
                 $wed[] = date("Y-m-d", strtotime($day)). " ".$result."<br>";
                 }  
                }
                 return  $wed;
                }
                $wed = getDays($year,$month);
                print_r($wed);
                

                【讨论】:

                  【解决方案11】:

                  如果没有给出 DateTime,您需要知道一个日期的日期 - 例如 unix 时代的开始(1970 年 1 月 1 日)。

                  从那里开始,您只需找到第一个星期三,然后从那里找到您的月份。记住闰年,你很好。

                  显然,它不是世界上最有效的算法,但它可以胜任。

                  【讨论】:

                  • 我认为他正在查找给定月份的所有星期三,由月份和年份值指定。
                  • 我知道 :) ... 上述算法的第一部分与到达给定月份的第一个星期三的过程有关。如果没有给出任何其他内容,则必须从某种“锚定”日开始
                  • @playcat-您误解了这个问题-查看其他答案
                  • 嗯...我可以发誓它最初并没有说 DateTime... 你确定你没有编辑问题吗?我评论了你的问题,建议如果 DateTime 可用,这项任务很容易......
                  • @playcat- 问题没有被编辑——如果你会看到它,那么 SO 上的所有编辑都是可见的
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-07-09
                  • 1970-01-01
                  • 2022-01-21
                  • 1970-01-01
                  • 2011-03-17
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多