计算X周内每周四和周日的日期



我用PHP为在线电子竞技联赛编写了一个循环赛生成器,我需要计算锦标赛中每场比赛的日期。比赛在每周四和周日进行,持续数周(周数取决于参赛队伍的数量)。给定起始周和周数,计算这些日期的最佳方法是什么?

我猜它需要使用DateTime, DateInterval和DatePeriod的一些组合;但是我不知道该怎么做。

更新:很抱歉之前没有提供代码。这是我最初想到的解决方案。我不知道是否有更简单的方法。生成日期的函数名为submitSchedule。

<html>
<body>
<?php
function roundRobin($teams) {
    $len = count($teams);
    $schedule = array();
    for ($i = 0; $i < $len - 1; $i++)
    {
        $home = array_slice($teams, 0, $len / 2);
        $away = array_slice($teams, $len / 2);
        $day = array();
        for ($j = 0; $j < $len / 2; $j++)
        {
            array_push($day, array($home[$j], $away[$j]));
        }
        array_push($schedule, $day);
        $temp = $away[0];
        for ($j = 0; $j < count($away) - 1; $j++)
        {
            $away[$j] = $away[$j + 1];
        }
        $away[count($away) - 1] = $home[count($home) - 1];
        for ($j = count($home) - 1; $j > 1; $j--)
        {
            $home[$j] = $home[$j - 1];
        }
        $home[1] = $temp;
        $teams = array_merge($home, $away);
    }
    return $schedule;
}
function roundRobinBalanced($teams)
{
    $schedule = roundRobin($teams);
    for ($i = 1; $i < count($schedule); $i+=2)
    {
        $schedule[$i][0] = array_reverse($schedule[$i][0]);
    }
    return $schedule;
}
function doubleRoundRobinBalanced($teams)
{
    $sched2 = roundRobinBalanced($teams);
    for ($i = 0; $i < count($sched2); $i++)
    {
        $sched2[$i] = array_reverse($sched2[$i]);
    }
    return array_merge(roundRobinBalanced($teams), $sched2);
}
function tripleRoundRobinBalanced($teams)
{
    return array_merge(doubleRoundRobinBalanced($teams), roundRobinBalanced($teams));
}
function submitSchedule($schedule, $start, $intervals, &$con)
{
    mysqli_query($con, "TRUNCATE TABLE matches");
    $curDate = $start;
    echo "<pre>";
    for ($i = 0; $i < count($schedule); $i++)
    {
        for ($j = 0; $j < count($schedule[$i]); $j++)
        {
            $temp0 = $schedule[$i][$j][0];
            $temp1 = $schedule[$i][$j][1];
            $temp2 = date_format($curDate, "Y-m-d");
            mysqli_query($con,"INSERT INTO matches (T1ID, T2ID, gameDate) VALUES ('$temp0', '$temp1', '$temp2')");
            echo "<span style="background:lightblue;">( " . date_format(new DateTime(), "Y-m-d H:i:s") . " )</span>" . "> INSERT INTO matches (T1ID, T2ID, gameDate) VALUES (". $schedule[$i][$j][0] . ", " . $schedule[$i][$j][1] . ", "" . date_format($curDate, "Y-m-d") . "")<br>";
        }
        date_add($curDate, date_interval_create_from_date_string($intervals[$i % count($intervals)]));
    }
    echo "</pre>";
}
$teams = array();
$con=mysqli_connect("localhost:3306","root","REMOVED","schedule");
// Check connection
if (mysqli_connect_errno()) {
    echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
//Select all items from the 'teams' table and order them first in descending order by points, then in ascending order by 'teamName'
$result = mysqli_query($con,"SELECT * FROM teams");
while($row = mysqli_fetch_array($result))
{
    array_push($teams, $row['TID']);
}
if (count($teams) % 2 == 1)
{
    array_push($teams, null);
}
shuffle($teams);
$schedule = tripleRoundRobinBalanced($teams);
// echo "<pre>" . json_encode($schedule, JSON_PRETTY_PRINT, JSON_FORCE_OBJECT) . "</pre>";
echo "<pre>";
print_r($schedule);
echo "</pre>";
// ---- List of possible DateTime expressions ----
// thursday
// next thursday
// YYYY-MM-DD
// DD/MM/yy
// thursday + 1 day
$start = new DateTime("thursday"); // Indicates the date of the first game
$jump = array("3 days", "4 days"); // Indicates the time intervals of each game (e.g. If day 1 starts on thursday, day 2 starts on sunday, day 3 starts on thursday, etc.)
submitSchedule($schedule, $start, $jump, $con);
mysqli_close($con);
?>
</body>
</html>

实现这一点的方法是使用PHP的DateTime类。它们真的非常有用。我建议用这样一个小函数:-

/**
 * @param $startWeek ISO week number of the first week
 * @param $numWeeks  The number of weeks to run including the first
 *
 * @return DateTime[] An array of DateTime objects
 */
function getPlayDays($startWeek, $numWeeks)
{
    $numWeeks --;
    $result = [];
    $currYear = (int)(new DateTime())->format('Y');
    $oneDay = new DateInterval('P1D');
    // Start on the first Thursday of the given week.
    $startDate = (new DateTime())->setISODate($currYear, $startWeek, 4);
    $endDate = clone $startDate;
    $endDate->add(new DateInterval("P{$numWeeks}W"));
    // End on the Sunday of the last week.
    $endDate->setISODate((int)$endDate->format('o'), (int)$endDate->format('W'), 7);
    $period = new DatePeriod($startDate, $oneDay, $endDate->add($oneDay));
    foreach($period as $day){
        if(4 === (int)$day->format('N') || 7 === (int)$day->format('N') ){
            $result[] = $day;
        }
    }
    return $result;
}
foreach(getPlayDays(1, 3) as $playDay){
    var_dump($playDay->format('D m-d-Y'));
}

您没有指定如何确定起始周,所以我假设是ISO周号。

输出

: -

string 'Thu 01-02-2014' (length=14)
string 'Sun 01-05-2014' (length=14)
string 'Thu 01-09-2014' (length=14)
string 'Sun 01-12-2014' (length=14)
string 'Thu 01-16-2014' (length=14)
string 'Sun 01-19-2014' (length=14)

看到它在工作

DateTime手册。

由于内置的DateTime类的魔力,该函数将非常愉快地处理DST更改,闰年和接近一年开始和结束的星期:)

证明或STFU

看一下strtotime函数:

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

你可以这样做:

$startDate = "May 15, 2014";
$startDate = strtotime($startDate);

你可以通过简单地加上三天来得到周日比赛的开始:

$nextDate = strtotime("+3 day", $startDate);

你的问题有点模糊,但我认为这就是你要问的。

假设您有起始周当天的时间戳(06:00 AM时间)…以后每隔一个日期为7天(86400秒* 7)。

让我们假设你将运行这个52周(1年)

$firstThu = 1234567890;
$firstSun = 9876543210;
$nextThus = array();
$nextSuns = array();
for($i=0; $i<52; $i++) {
    $nextThus[] = date('d/m/Y', $firstThu + (86400 * 7 * $i));
    $nextSuns[] = date('d/m/Y', $firstSun + (86400 * 7 * $i));
}

在循环结束时,您将得到包含所有52周日期的两个数组。

相关内容

  • 没有找到相关文章

最新更新