Get the First or Last Friday in a Month

后端 未结 12 2359
有刺的猬
有刺的猬 2020-11-29 12:12

I\'m trying to write a calendar function like this

function get_date($month, $year, $week, $day, $direction)
{
    ....
}

$week

12条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-29 12:34

    No need for calculations or loops - this is very easy to do with strtotime():

    Find the the Nth or Last occurrence of a particular day of a particular a month:

    /////////////////////////////////////////////////////////////////
    // Quick Code
    /////////////////////////////////////////////////////////////////
    
    // Convenience mapping.
    $Names = array( 0=>"Sun", 1=>"Mon", 2=>"Tue", 3=>"Wed", 4=>"Thu", 5=>"Fri", 6=>"Sat" );
    
    // Specify what we want
    // In this example, the Second Monday of Next March
    $tsInMonth = strtotime('March');
    $Day = 1;
    $Ord = 2;
    
    // The actual calculations
    $ThisMonthTS = strtotime( date("Y-m-01", $tsInMonth ) );
    $NextMonthTS = strtotime( date("Y-m-01", strtotime("next month", $tsInMonth) ) );
    $DateOfInterest = (-1 == $Ord) 
        ? strtotime( "last ".$Names[$Day], $NextMonthTS ) 
        : strtotime( $Names[$Day]." + ".($Ord-1)." weeks", $ThisMonthTS ); 
    
    
    /////////////////////////////////////////////////////////////////
    // Explanation
    /////////////////////////////////////////////////////////////////
    
    // Specify the month of which we are interested.
    // You can use any timestamp inside that month, I'm using strtotime for convenience.
    $tsInMonth = strtotime('March');
    
    // The day of interest, ie: Friday.  
    // It can be 0=Sunday through 6=Saturday (Like 'w' from date()).
    $Day = 5;
    
    // The occurrence of this day in which we are interested.  
    // It can be 1, 2, 3, 4 for the first, second, third, and fourth occurrence of the day in question in the month in question.
    // You can also use -1 to fine the LAST occurrence.  That will return the fifth occurrence if there is one, else the 4th.
    $Ord = 3;
    
    ////////////////////////////////////////////////////////////////
    // We now have all the specific values we need.
    // The example values above specify the 3rd friday of next march
    ////////////////////////////////////////////////////////////////
    
    // We need the day name that corresponds with our day number to pass to strtotime().
    // This isn't really necessary = we could just specify the string in the first place, but for date calcs, you are more likely to have the day number than the string itself, so this is convenient.
    $Names = array( 0=>"Sun", 1=>"Mon", 2=>"Tue", 3=>"Wed", 4=>"Thu", 5=>"Fri", 6=>"Sat" );
    
    // Calculate the timestamp at midnight of the first of the month in question.
    // Remember $tsInMonth is any date in that month.
    $ThisMonthTS = strtotime( date("Y-m-01", $tsInMonth ) );
    
    // Calculate the timestamp at midnight of the first of the FOLLOWING month.
    // This will be used if we specify -1 for last occurrence.
    $NextMonthTS = strtotime( date("Y-m-01", strtotime("next month", $tsInMonth) ) );
    
    // Now we just format the values a bit and pass them to strtotime().
    // To find the 1,2,3,4th occurrence, we work from the first of the month forward.
    // For the last (-1) occurence,work we work back from the first occurrence of the following month.
    $DateOfInterest = (-1 == $Ord) ?
        strtotime( "last ".$Names[$Day], $NextMonthTS ) : // The last occurrence of the day in this month.  Calculated as "last dayname" from the first of next month, which will be the last one in this month. 
        strtotime( $Names[$Day]." + ".($Ord-1)." weeks", $ThisMonthTS ); // From the first of this month, move to "next dayname" which will be the first occurrence, and then move ahead a week for as many additional occurrences as you need.
    

提交回复
热议问题