简体   繁体   English

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

[英]I have the week number of a month, and want to get the first date within that week in PHP

Assuming I have the following given information:假设我有以下给定信息:

$year = 2020; 
$month = 7; 

$week_nr_of_month = 2; 

$first_date_in_that_week = ?; 

I want to know the first date within that week number of month.我想知道该月数周内的第一个日期。 So in my current situation the output should be the 2020-07-06所以在我目前的情况下 output 应该是 2020-07-06

How can I calculate this?我该如何计算? Thank you.谢谢你。

I have something like this:我有这样的事情:

<?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)
);

Tested output:测试 output:

string(10) "2020-07-01"
string(10) "2020-07-06"
string(10) "2020-07-13"
string(10) "2020-07-20"
string(10) "2020-07-27"
string(10) "2020-08-03"

string(10) "2020-08-01"
string(10) "2020-08-03"
string(10) "2020-08-10"
string(10) "2020-08-17"
string(10) "2020-08-24"
string(10) "2020-08-31"

string(10) "2014-12-01"
string(10) "2014-12-08"
string(10) "2014-12-15"

Here is my solution:这是我的解决方案:

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

This algorithm uses the number of seconds since the Unix epoch.该算法使用自 Unix 时期以来的秒数。 This is an integer so all the calculations are done by adding or multiplying integers which should be quite fast.这是一个 integer 所以所有的计算都是通过加或乘整数来完成的,这应该很快。 The conversion between a date and an integer only happens once at the start and once at the end of the function.日期和 integer 之间的转换仅在 function 的开头和结尾发生一次。

As an aside, I found finding meaningful names for the start of the week when I was referring to so many different starts of weeks/months quite a challenge.顺便说一句,当我提到这么多不同的周/月开始时,我发现为周开始找到有意义的名称是一个挑战。

For comparison I've used the same tests as in blahy's answer:为了比较,我使用了与 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)
);
string(10) "2020-07-01"
string(10) "2020-07-06"
string(10) "2020-07-13"
string(10) "2020-07-20"
string(10) "2020-07-27"
string(10) "2020-08-03"
string(10) "2020-08-01"
string(10) "2020-08-03"
string(10) "2020-08-10"
string(10) "2020-08-17"
string(10) "2020-08-24"
string(10) "2020-08-31"
string(10) "2014-12-01"
string(10) "2014-12-08"
string(10) "2014-12-15"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM