Getting all dates for Mondays and Tuesdays for the next year

前端 未结 4 1293
长发绾君心
长发绾君心 2020-11-27 21:18

I need to output a list of dates (only Mondays and Tuesdays) for the next 12 months from current date like so:

Jan 2010
Tue 12 Jan 2010
Mon 18 Jan 2010<

相关标签:
4条回答
  • 2020-11-27 21:44

    This is an interesting one. Here's how I'd do it with functions, though it may warrant its own class to really be modular and reusable:

    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',
    );
    

    Then I need some utility functions to see how the dates run, and what dates are excluded:

    // 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);
    }
    

    Now we just need to iterate over every day of the next 365 (the next year) and check to see if they're Tuesday or Wednesday and not on the excluded list. We store this in $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;
        }
    }
    

    You can print_r() it, or to get the display you want, we do this:

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

    Here's the result as of today, January 11, 2010:

    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
    
    0 讨论(0)
  • 2020-11-27 21:49

    in a funny coincidence, because today is monday, it is skipping one monday value, that's why they appear out of order. yesterday it would have worked fine.

    i.e. your "+ 0 Monday" is NEXT monday, not today.

    you may want to look into the "N" format character for date().

    0 讨论(0)
  • 2020-11-27 21:50

    Ok now that your computers date is Wednesday you want to print the Mondays before the Tuesdays as the next Monday is closer to Wednesday than the next Tuesday. So try this:

    $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'));
       }
    }
    
    0 讨论(0)
  • 2020-11-27 22:03
    <?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);
    
    0 讨论(0)
提交回复
热议问题