我有一个月的周数,希望在PHP中获得该周内的第一个日期

我有一个月的周数,希望在PHP中获得该周内的第一个日期,php,date,Php,Date,假设我有以下给定信息: $year = 2020; $month = 7; $week_nr_of_month = 2; $first_date_in_that_week = ?; 我想知道那一周内的第一个日期。所以在我目前的情况下,产量应该是2020-07-06 我怎么计算这个呢?谢谢。我有这样的东西: <?php function myDate(int $year, int $month, int $week): string { $firstDayDate =

假设我有以下给定信息:

$year = 2020; 
$month = 7; 

$week_nr_of_month = 2; 

$first_date_in_that_week = ?; 

我想知道那一周内的第一个日期。所以在我目前的情况下,产量应该是2020-07-06


我怎么计算这个呢?谢谢。

我有这样的东西:

<?php

function myDate(int $year, int $month, int $week): string {
  $firstDayDate = DateTime::createFromFormat('j-n-Y', '1-'.$month.'-'.$year);
  $firstDayDate->setTime(0,0);

  $firstMondayDate = (clone $firstDayDate)->modify('first monday of this month');
  $modificator = $week - 2;

  if ($firstMondayDate->format('d') === $firstDayDate->format('d')) {
    $modificator++;
  }

  if ($modificator < 0) {
    return $firstDayDate->format('Y-m-d');
  }

  $wantedWeekDate = (clone $firstMondayDate)->add(new DateInterval('P'.($modificator*7).'D'));
  
  return $wantedWeekDate->format('Y-m-d');
}

var_dump(
myDate(2020, 7, 1),
myDate(2020, 7, 2),
myDate(2020, 7, 3),
myDate(2020, 7, 4),
myDate(2020, 7, 5),
myDate(2020, 7, 6),

myDate(2020, 8, 1),
myDate(2020, 8, 2),
myDate(2020, 8, 3),
myDate(2020, 8, 4),
myDate(2020, 8, 5),
myDate(2020, 8, 6),

myDate(2014, 12, 1),
myDate(2014, 12, 2),
myDate(2014, 12, 3)
);

我有这样的想法:

<?php

function myDate(int $year, int $month, int $week): string {
  $firstDayDate = DateTime::createFromFormat('j-n-Y', '1-'.$month.'-'.$year);
  $firstDayDate->setTime(0,0);

  $firstMondayDate = (clone $firstDayDate)->modify('first monday of this month');
  $modificator = $week - 2;

  if ($firstMondayDate->format('d') === $firstDayDate->format('d')) {
    $modificator++;
  }

  if ($modificator < 0) {
    return $firstDayDate->format('Y-m-d');
  }

  $wantedWeekDate = (clone $firstMondayDate)->add(new DateInterval('P'.($modificator*7).'D'));
  
  return $wantedWeekDate->format('Y-m-d');
}

var_dump(
myDate(2020, 7, 1),
myDate(2020, 7, 2),
myDate(2020, 7, 3),
myDate(2020, 7, 4),
myDate(2020, 7, 5),
myDate(2020, 7, 6),

myDate(2020, 8, 1),
myDate(2020, 8, 2),
myDate(2020, 8, 3),
myDate(2020, 8, 4),
myDate(2020, 8, 5),
myDate(2020, 8, 6),

myDate(2014, 12, 1),
myDate(2014, 12, 2),
myDate(2014, 12, 3)
);
以下是我的解决方案:

function firstDayOfWeekInMonth($year, $month, $week)
{
    $firstOfMonth = strtotime("$year-$month-1");
    $format = 'Y-m-d';
    if ($week == 1) {
        return date($format, $firstOfMonth);
    } else {
        $secondsInOneDay = 60 * 60 * 24;
        $secondInOneWeek = $secondsInOneDay * 7;
        $dayNumberOfFirstOfMonth = date('w', $firstOfMonth); //eg Monday = 1, Tuesday = 2, etc.
        $offsetToStartOfWeek = ($dayNumberOfFirstOfMonth - 1) * $secondsInOneDay; // eg Monday is 0 days from Monday, Tuesday is 1 day from Monday etc.
        $startOfWeek1 = $firstOfMonth - $offsetToStartOfWeek; //could be in previous month
        $StartOfWeekN = $startOfWeek1 + ($week - 1) * $secondsInOneWeek; // week-2 is 1-week ahead of week-1's Monday
        return date($format, $StartOfWeekN);
    }
}
此算法使用自Unix纪元以来的秒数。这是一个整数,所以所有的计算都是通过将整数相加或相乘来完成的,这应该非常快。日期和整数之间的转换只在函数开始和结束时发生一次

顺便说一句,当我提到许多不同的周初/月初时,我发现为周初找到有意义的名字是一个相当大的挑战

为了进行比较,我使用了与blahy回答中相同的测试:

var_dump(
firstDayOfWeekInMonth(2020, 7, 1),
firstDayOfWeekInMonth(2020, 7, 2),
firstDayOfWeekInMonth(2020, 7, 3),
firstDayOfWeekInMonth(2020, 7, 4),
firstDayOfWeekInMonth(2020, 7, 5),
firstDayOfWeekInMonth(2020, 7, 6),

firstDayOfWeekInMonth(2020, 8, 1),
firstDayOfWeekInMonth(2020, 8, 2),
firstDayOfWeekInMonth(2020, 8, 3),
firstDayOfWeekInMonth(2020, 8, 4),
firstDayOfWeekInMonth(2020, 8, 5),
firstDayOfWeekInMonth(2020, 8, 6),

firstDayOfWeekInMonth(2014, 12, 1),
firstDayOfWeekInMonth(2014, 12, 2),
firstDayOfWeekInMonth(2014, 12, 3)
);
以下是我的解决方案:

function firstDayOfWeekInMonth($year, $month, $week)
{
    $firstOfMonth = strtotime("$year-$month-1");
    $format = 'Y-m-d';
    if ($week == 1) {
        return date($format, $firstOfMonth);
    } else {
        $secondsInOneDay = 60 * 60 * 24;
        $secondInOneWeek = $secondsInOneDay * 7;
        $dayNumberOfFirstOfMonth = date('w', $firstOfMonth); //eg Monday = 1, Tuesday = 2, etc.
        $offsetToStartOfWeek = ($dayNumberOfFirstOfMonth - 1) * $secondsInOneDay; // eg Monday is 0 days from Monday, Tuesday is 1 day from Monday etc.
        $startOfWeek1 = $firstOfMonth - $offsetToStartOfWeek; //could be in previous month
        $StartOfWeekN = $startOfWeek1 + ($week - 1) * $secondsInOneWeek; // week-2 is 1-week ahead of week-1's Monday
        return date($format, $StartOfWeekN);
    }
}
此算法使用自Unix纪元以来的秒数。这是一个整数,所以所有的计算都是通过将整数相加或相乘来完成的,这应该非常快。日期和整数之间的转换只在函数开始和结束时发生一次

顺便说一句,当我提到许多不同的周初/月初时,我发现为周初找到有意义的名字是一个相当大的挑战

为了进行比较,我使用了与blahy回答中相同的测试:

var_dump(
firstDayOfWeekInMonth(2020, 7, 1),
firstDayOfWeekInMonth(2020, 7, 2),
firstDayOfWeekInMonth(2020, 7, 3),
firstDayOfWeekInMonth(2020, 7, 4),
firstDayOfWeekInMonth(2020, 7, 5),
firstDayOfWeekInMonth(2020, 7, 6),

firstDayOfWeekInMonth(2020, 8, 1),
firstDayOfWeekInMonth(2020, 8, 2),
firstDayOfWeekInMonth(2020, 8, 3),
firstDayOfWeekInMonth(2020, 8, 4),
firstDayOfWeekInMonth(2020, 8, 5),
firstDayOfWeekInMonth(2020, 8, 6),

firstDayOfWeekInMonth(2014, 12, 1),
firstDayOfWeekInMonth(2014, 12, 2),
firstDayOfWeekInMonth(2014, 12, 3)
);

$week\u nr\u of\u month=1的输出应该是什么?2020-07-01还是2020-06-29?2你说的2020-07-06,意思是3->13,4->20。2020-07-27有5个月?您好-1个月的$week\u nr\u的输出应为2020-07-01,2个月的输出应为2020-07-06,3个月的输出应为2020-07-13,因此4个月的$week\u nr\u的输出应为1?2020-07-01还是2020-06-29?2你说的2020-07-06,意思是3->13,4->20。2020-07-27的月内有5周?Hi-1月的周内输出应为2020-07-01,2月的输出应为2020-07-06,3月的输出应为2020-07-13,以此类推