获得一个月的第一个或最后一个星期五

Zah*_*aka 12 php datetime

我正在尝试编写这样的日历函数

function get_date($month, $year, $week, $day, $direction)
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

$week是一个整数(1,2,3 ......),$ day是一天(太阳,周一,......)或数字,以较容易的为准.方向有点混乱,因为它做了不同的计算.

举个例子,我们来电

get_date(5, 2009, 1, 'Sun', 'forward');

它使用默认值,并获得5月的第一个星期日,即2009-05-03.如果我们打电话

get_date(5, 2009, 2, 'Sun', 'backward');

,它返回五月的最后一个星期日,即2009-05-24.

Mar*_*som 22

与语言无关的版本:

要获得该月的第一天,请从该月的第一天开始:yyyy-mm-01.使用任何可用的函数来给出与星期几相对应的数字.从你想要的那天减去那个数字; 例如,如果该月的第一天是星期三(2)并且您正在寻找星期五(4),则从4减去2,留下2.如果答案是否定的,则添加7.最后将其添加到第一天这个月; 就我而言,第一个星期五将是第三个星期五.

要获得本月的最后一个星期五,请找到下个月的第一个星期五并减去7天.


Mar*_*odF 12

也许它可以更快...
这对代码非常有趣.

请注意,$direction前锋为1,后退为-1,以便缓解情况:)
此外,$day星期一的值为1,星期日的值为7.

function get_date($month, $year, $week, $day, $direction) {
  if($direction > 0)
    $startday = 1;
  else
    $startday = date('t', mktime(0, 0, 0, $month, 1, $year));

  $start = mktime(0, 0, 0, $month, $startday, $year);
  $weekday = date('N', $start);

  if($direction * $day >= $direction * $weekday)
    $offset = -$direction * 7;
  else
    $offset = 0;

  $offset += $direction * ($week * 7) + ($day - $weekday);
  return mktime(0, 0, 0, $month, $startday + $offset, $year);
}
Run Code Online (Sandbox Code Playgroud)

我用几个例子对它进行了测试,似乎总是有效,但一定要仔细检查一下;)


Vol*_*erK 8

strtotime()可以帮助你.例如

<?php
$tsFirst = strtotime('2009-04-00 next friday');
$tsLast = strtotime('2009-05-01 last friday');
echo date(DATE_RFC850, $tsFirst), " | ", date(DATE_RFC850, $tsLast);
Run Code Online (Sandbox Code Playgroud)版画
Friday, 03-Apr-09 00:00:00 CEST | Friday, 24-Apr-09 00:00:00 CEST


eki*_*aby 8

PHP的内置时间函数使这一点变得简单.

http://php.net/manual/en/function.strtotime.php

// Get first Friday of next month.
$timestamp = strtotime('first fri of next month');

// Get second to last Friday of the current month.
$timestamp = strtotime('last fri of this month -7 days');

// Format a timestamp as a human-meaningful string.
$formattedDate = date('F j, Y', strtotime('first wed of last month'));
Run Code Online (Sandbox Code Playgroud)

请注意,我们总是希望确保我们已经定义了正确的时区strtotime以便PHP 使用,以便PHP了解计算相对于机器认为的时区的时间戳的位置.

date_default_timezone_set('America/New_York');
$formattedDate = date('F j, Y', strtotime('first wed of last month +1 week'));
Run Code Online (Sandbox Code Playgroud)


Eli*_*Eli 6

无需计算或循环 - 使用strtotime()非常容易:

查找特定月份的特定日期的第N次或最后一次出现:

/////////////////////////////////////////////////////////////////
// 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.
Run Code Online (Sandbox Code Playgroud)