【问题标题】:Getting all dates for Mondays and Tuesdays for the next year获取下一年周一和周二的所有日期
【发布时间】:2010-01-11 23:36:48
【问题描述】:

我需要从当前日期开始输出未来 12 个月的日期列表(仅限周一和周二),如下所示:

2010 年 1 月
2010 年 1 月 12 日星期二
2010 年 1 月 18 日星期一
2010 年 1 月 19 日星期二
2010 年 1 月 25 日星期一
2010 年 2 月
2010 年 2 月 2 日星期二
2010 年 2 月 8 日星期一
2010 年 2 月 9 日星期二
2010 年 2 月 15 日星期一
2010 年 2 月 16 日星期二
2010 年 2 月 22 日星期一
2010 年 3 月
2010 年 3 月 9 日星期二
2010 年 3 月 15 日星期一
2010 年 3 月 16 日星期二
...

作为 PHP 新手,我认为 strtotime 并在接下来的 52 周内循环是最好的方法。

$blockedDatesInput = "08 Mar 2010,12 Apr 2010"; // dont show these dates
$blockedDates = explode ("," , $blockedDatesInput); // convert to array
$currentMonth = ""; // current month marker

// loop over the next 52 weeks to find Mondays and Tuesdays
for($i=0; $i<=52; $i++){
// build the month header
$monthReference = date("M Y", strtotime('+'.$i.' Week'));

// check if date exists in $blockeddate
if (!in_array(date("d M Y", strtotime('+'.$i.' Monday')), $blockedDates) || 
    !in_array(date("d M Y", strtotime('+'.$i.' Tuesday')), $blockedDates) ) {
     // check if we have to show a new month
     if(strcmp($monthReference, $currentMonth) <> 0){
       echo $monthReference.'<br />',"\n";
     }else{
      // output the dates
      echo date("D d M Y", strtotime('+'.$i.' Monday')).'<br />',"\n";
      echo date("D d M Y", strtotime('+'.$i.' Tuesday')).'<br />',"\n";
     }
       $currentMonth = date("M Y", strtotime('+'.$i.' Week'));
   }
}

但是我的代码的输出是

2010 年 1 月
2010 年 1 月 18 日星期一
2010 年 1 月 12 日星期二
2010 年 1 月 25 日星期一
2010 年 1 月 19 日星期二
2010 年 2 月
2010 年 2 月 8 日星期一
2010 年 2 月 2 日星期二
2010 年 2 月 15 日星期一
2010 年 2 月 9 日星期二
2010 年 2 月 22 日星期一
2010 年 2 月 16 日星期二
2010 年 3 月
2010 年 3 月 8 日星期一
2010 年 3 月 2 日星期二
2010 年 3 月 15 日星期一
2010 年 3 月 9 日星期二
2010 年 3 月 22 日星期一
2010 年 3 月 16 日星期二
2010 年 3 月 29 日星期一
2010 年 3 月 23 日星期二

如您所见,日期的顺序不正确,我不知所措。

有没有更优雅/简单的方法来解决这个问题?

使用的 PHP 版本是 5.2.11,短期内没有前景 5.3 :-(

感谢您的帮助。

Aly 建议修改以下代码。 将计算机日期从 2010 年 12 月 1 日星期二更改为 2010 年 1 月 13 日星期三,以测试输出。

$blockedDatesInput = "08 Mar 2010,12 Apr 2010"; // dont show these dates
$blockedDates = explode ("," , $blockedDatesInput); // convert to array
$currentMonth = ""; // current month marker

// loop over the next 52 weeks to find Mondays and Tuesdays
for($i=0; $i<=52; $i++){
// build the month header
$monthReference = date("M Y", strtotime('+'.$i.' Week'));

// check if date exists in $blockeddate
if (!in_array(date("d M Y", strtotime('+'.$i.' Monday')), $blockedDates) || 
    !in_array(date("d M Y", strtotime('+'.$i.' Tuesday')), $blockedDates) ) {
     // check if we have to show a new month
     if(strcmp($monthReference, $currentMonth) <> 0){
       echo $monthReference.'<br />',"\n";
     }else{
      // output the dates (changed the order as suggested by Aly)
      echo date("D d M Y", strtotime('+'.$i.' Tuesday')).'<br />',"\n";
      echo date("D d M Y", strtotime('+'.$i.' Monday')).'<br />',"\n";          
     }
       $currentMonth = date("M Y", strtotime('+'.$i.' Week'));
   }
}

以错误的顺序再次输出。

2010 年 1 月
2010 年 1 月 19 日星期二
2010 年 1 月 18 日星期一
2010 年 1 月 26 日星期二
2010 年 1 月 25 日星期一
2010 年 2 月
2010 年 2 月 9 日星期二
2010 年 2 月 8 日星期一
2010 年 2 月 16 日星期二
2010 年 2 月 15 日星期一
2010 年 2 月 23 日星期二
2010 年 2 月 22 日星期一

【问题讨论】:

    标签: php strtotime


    【解决方案1】:

    这是一个有趣的问题。以下是我使用函数的方法,尽管它可能保证它自己的类真正是模块化和可重用的:

    Set up my date formats and excluded dates
    define('INTERNAL_FORMAT', 'Y-m-d');
    define('DISPLAY_MONTH_FORMAT', 'M Y');
    define('DISPLAY_DAY_FORMAT', 'D d M Y');
    // format excluded dates as YYYY-MM-DD, date('Y-m-d'):
    $excluded_dates = array(
        '2010-03-09',
        '2010-04-13',
    );
    

    然后我需要一些实用函数来查看日期是如何运行的,以及哪些日期被排除在外:

    // date('w') returns a string numeral as follows:
    //   '0' Sunday
    //   '1' Monday
    //   '2' Tuesday
    //   '3' Wednesday
    //   '4' Thursday
    //   '5' Friday
    //   '6' Saturday
    function isTuesday($date) {
        return date('w', strtotime($date)) === '2';
    }
    function isWednesday($date) {
        return date('w', strtotime($date)) === '3';
    }
    
    // handle the excluded dates
    function isExcludedDate($internal_date) {
        global $excluded_dates;
        return in_array($internal_date, $excluded_dates);
    }
    

    现在我们只需要遍历下一个 365(下一年)的每一天,并检查它们是星期二还是星期三,并且不在排除列表中。我们将其存储在$months_and_dates:

    $start_date = date(INTERNAL_FORMAT);
    
    // something to store months and days
    $months_and_dates = array();
    
    // loop over 365 days and look for tuesdays or wednesdays not in the excluded list
    foreach(range(0,365) as $day) {
        $internal_date = date(INTERNAL_FORMAT, strtotime("{$start_date} + {$day} days"));
        $this_day = date(DISPLAY_DAY_FORMAT, strtotime($internal_date));
        $this_month = date(DISPLAY_MONTH_FORMAT, strtotime($internal_date));
        if ((isTuesday($internal_date) || isWednesday($internal_date)) 
            && !isExcludedDate($internal_date)) {
                $months_and_dates[$this_month][] = $this_day;
        }
    }
    

    你可以print_r()它,或者得到你想要的显示,我们这样做:

    foreach($months_and_dates as $month => $days) {
        print $month . "<br>";
        print implode('<br>', $days);
        print "<br>";
    }
    

    这是 2010 年 1 月 11 日今天的结果:

    Jan 2010
    Tue 12 Jan 2010
    Wed 13 Jan 2010
    Tue 19 Jan 2010
    Wed 20 Jan 2010
    Tue 26 Jan 2010
    Wed 27 Jan 2010
    Feb 2010
    Tue 02 Feb 2010
    Wed 03 Feb 2010
    Tue 09 Feb 2010
    Wed 10 Feb 2010
    Tue 16 Feb 2010
    Wed 17 Feb 2010
    Tue 23 Feb 2010
    Wed 24 Feb 2010
    Mar 2010
    Tue 02 Mar 2010
    Wed 03 Mar 2010
    Wed 10 Mar 2010
    Tue 16 Mar 2010
    Wed 17 Mar 2010
    Tue 23 Mar 2010
    Wed 24 Mar 2010
    Tue 30 Mar 2010
    Wed 31 Mar 2010
    Apr 2010
    Tue 06 Apr 2010
    Wed 07 Apr 2010
    Wed 14 Apr 2010
    Tue 20 Apr 2010
    Wed 21 Apr 2010
    Tue 27 Apr 2010
    Wed 28 Apr 2010
    May 2010
    Tue 04 May 2010
    Wed 05 May 2010
    Tue 11 May 2010
    Wed 12 May 2010
    Tue 18 May 2010
    Wed 19 May 2010
    Tue 25 May 2010
    Wed 26 May 2010
    Jun 2010
    Tue 01 Jun 2010
    Wed 02 Jun 2010
    Tue 08 Jun 2010
    Wed 09 Jun 2010
    Tue 15 Jun 2010
    Wed 16 Jun 2010
    Tue 22 Jun 2010
    Wed 23 Jun 2010
    Tue 29 Jun 2010
    Wed 30 Jun 2010
    Jul 2010
    Tue 06 Jul 2010
    Wed 07 Jul 2010
    Tue 13 Jul 2010
    Wed 14 Jul 2010
    Tue 20 Jul 2010
    Wed 21 Jul 2010
    Tue 27 Jul 2010
    Wed 28 Jul 2010
    Aug 2010
    Tue 03 Aug 2010
    Wed 04 Aug 2010
    Tue 10 Aug 2010
    Wed 11 Aug 2010
    Tue 17 Aug 2010
    Wed 18 Aug 2010
    Tue 24 Aug 2010
    Wed 25 Aug 2010
    Tue 31 Aug 2010
    Sep 2010
    Wed 01 Sep 2010
    Tue 07 Sep 2010
    Wed 08 Sep 2010
    Tue 14 Sep 2010
    Wed 15 Sep 2010
    Tue 21 Sep 2010
    Wed 22 Sep 2010
    Tue 28 Sep 2010
    Wed 29 Sep 2010
    Oct 2010
    Tue 05 Oct 2010
    Wed 06 Oct 2010
    Tue 12 Oct 2010
    Wed 13 Oct 2010
    Tue 19 Oct 2010
    Wed 20 Oct 2010
    Tue 26 Oct 2010
    Wed 27 Oct 2010
    Nov 2010
    Tue 02 Nov 2010
    Wed 03 Nov 2010
    Tue 09 Nov 2010
    Wed 10 Nov 2010
    Tue 16 Nov 2010
    Wed 17 Nov 2010
    Tue 23 Nov 2010
    Wed 24 Nov 2010
    Tue 30 Nov 2010
    Dec 2010
    Wed 01 Dec 2010
    Tue 07 Dec 2010
    Wed 08 Dec 2010
    Tue 14 Dec 2010
    Wed 15 Dec 2010
    Tue 21 Dec 2010
    Wed 22 Dec 2010
    Tue 28 Dec 2010
    Wed 29 Dec 2010
    Jan 2011
    Tue 04 Jan 2011
    Wed 05 Jan 2011
    Tue 11 Jan 2011
    

    【讨论】:

    • artlung 感谢您的帮助。比我想象的要复杂得多。但这是有道理的。在 Java 中,我也可以通过哈希图解决它。这个 php 东西对我来说很陌生 :-) 再次感谢
    • 没有Javascript的解决方案吗?
    【解决方案2】:

    一个有趣的巧合,因为今天是星期一,它跳过了一个星期一的值,这就是它们出现乱序的原因。昨天它会工作得很好。

    即你的“+ 0 Monday”是下一个星期一,而不是今天。

    您可能想查看 date() 的“N”格式字符。

    【讨论】:

    • 实际上在我的树林里已经是星期二 :-) 但是日期的顺序是错误的。我想帽子就是我要问的。
    【解决方案3】:

    好的,现在您的计算机日期是星期三,您想打印星期二之前的星期一,因为下星期一比下星期二更接近星期三。所以试试这个:

    $blockedDatesInput = "08 Mar 2010,12 Apr 2010"; // dont show these dates
    $blockedDates = explode ("," , $blockedDatesInput); // convert to array
    $currentMonth = ""; // current month marker
    
    // loop over the next 52 weeks to find Mondays and Tuesdays
    for($i=0; $i<=52; $i++){
    // build the month header
    $monthReference = date("M Y", strtotime('+'.$i.' Week'));
    
    // check if date exists in $blockeddate
    if (!in_array(date("d M Y", strtotime('+'.$i.' Monday')), $blockedDates) || 
        !in_array(date("d M Y", strtotime('+'.$i.' Tuesday')), $blockedDates) ) {
         // check if we have to show a new month
         if(strcmp($monthReference, $currentMonth) <> 0){
           echo $monthReference.'<br />',"\n";
         }else{
          // output the dates (changed the order as suggested by Aly)
          echo date("D d M Y", strtotime('+'.$i.' Monday')).'<br />',"\n";          
          echo date("D d M Y", strtotime('+'.$i.' Tuesday')).'<br />',"\n";
         }
           $currentMonth = date("M Y", strtotime('+'.$i.' Week'));
       }
    }
    

    【讨论】:

    • 我已按照您的建议更改了顺序,然后将我的 PC 日期更改为明天(2010 年 1 月 13 日),输出再次错误。所以我想我在这里遗漏了一些基本的东西。

      2010 年 1 月
      2010 年 1 月 19 日星期二
      2010 年 1 月 18 日星期一
      2010 年 1 月 26 日星期二
      2010 年 1 月 25 日星期一
      2010 年 2 月
      2 月 9 日星期二2010 年
      2010 年 2 月 8 日星期一
      2010 年 2 月 16 日星期二
      2010 年 2 月 15 日星期一
      2010 年 2 月 23 日星期二
      2010 年 2 月 22 日星期一

    • 你为什么还要更改你的电脑日期,做一个或另一个 - 你能用你的新代码和你的电脑显示的当前日期编辑你的帖子
    【解决方案4】:
    <?php
    /*
        @$listDaysOfWeek list days
        0 = Monday
        1 = Tuesday
        2 = Wednesday
        3 = Thursday
        4 = Friday
        5 = Saturday
        6 = Sunday
    */
    
    function DatesFromDaysOnWeek(\Datetime $objDateTime, int $numAddDays , array $listDaysOfWeek)
    {
        $listDaysOfWeek     = array_intersect($listDaysOfWeek, range(0,6) );
        sort($listDaysOfWeek);
    
        if(empty($listDaysOfWeek) || $numAddDays < 1)
            return [];
    
        $results = [];
        while ( $numAddDays > 0)
        {
            foreach($listDaysOfWeek as $numDay)
            {
                $infoDate = (object) getdate( $objDateTime->getTimestamp() );
                if($numDay != $infoDate->wday)
                    continue;
    
                array_push($results, $objDateTime->format('Y-m-d') );
                $numAddDays--;
            }
    
            $objDateTime->add(new \DateInterval('P1D'));
        }
    
        return $results;
    }
    
    #example:
    $list = DatesFromDaysOnWeek( (new \DateTime('2019-02-01')) , 4 , [1] );
    print_r($list);
    $list = DatesFromDaysOnWeek( (new \DateTime('2019-02-01')) , 4 , [2] );
    print_r($list);
    $list = DatesFromDaysOnWeek( (new \DateTime('2019-02-01')) , 4 , [3] );
    print_r($list);
    $list = DatesFromDaysOnWeek( (new \DateTime('2019-02-01')) , 4 , [4] );
    print_r($list);
    $list = DatesFromDaysOnWeek( (new \DateTime('2019-02-01')) , 4 , [5] );
    print_r($list);
    $list = DatesFromDaysOnWeek( (new \DateTime('2019-02-01')) , 4 , [6] );
    print_r($list);
    $list = DatesFromDaysOnWeek( (new \DateTime('2019-02-01')) , 4 , [0] );
    print_r($list);
    $list = DatesFromDaysOnWeek( (new \DateTime('2019-03-01')) , 100 , [1,2] );
    print_r($list);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      相关资源
      最近更新 更多