I have some code that generates fixtures, I am looking to add a fixture date to the code.
$totalRounds = $teams - 1;
$matchesPerRound = $teams / 2;
$rounds = array();
for ($i = 0; $i < $totalRounds; $i++) {
$rounds[$i] = array();
}
for ($round = 0; $round < $totalRounds; $round++) {
for ($match = 0; $match < $matchesPerRound; $match++) {
$home = ($round + $match) % ($teams - 1);
$away = ($teams - 1 - $match + $round) % ($teams - 1);
// Last team stays in the same place while the others
// rotate around it.
if ($match == 0) {
$away = $teams - 1;
}
$rounds[$round][$match] = "$user[$home]~$team[$home]#$user[$away]~$team[$away]";
}
}
$team is the amount of teams in the league.
I want to add a variable for every 4 days, and for every round of fixtures generated, I want to add 4 days onto the previous round.
For example, if today is 3rd may, i want 3rd may for first fixture, 7th may for second fixture, 11th may for third fixture.
By fixture i mean round which includes a set of fixtures!
How do I add 4 days to a strotime variable everytime the rounds increase?
Have you looked into strtotime? It allows syntax like the following:
$future_date = strtotime('+4 days');
$even_further_in_the_future = strtotime('+4 days', $future_date);
$arbitrary_start_date = strtotime('+4 days', strtotime('May 25th, 2010'));
If I understand your question correctly, you just want each round to have an associated date. You've got an array of $rounds, so could you not just create a correspondingly-keyed array to hold the round dates?
...
$rounds = array();
$roundDates = array();
$curTime = time();
for ($i = 0; $i < $totalRounds; $i++) {
$rounds[$i] = array();
$numDays = $i * 4;
$roundDates[$i] = strtotime("+".$numDays." days",$curTime);
}
foreach($roundDates as $time) echo date("Y-m-d",$time)."\n";
//gives
//2010-05-03
//2010-05-07
//2010-05-11
//etc
Related
How to get continue date next month based on number of parameters?
Example:
$loan = 4; //count from this month
$fixedDateEveryMonth = 28;
for($i=0 $i<=$loan; $i++)
{
echo $fixedDateEveryMonth."-".date("m-y");
}
So what I expected is to get below date:
28-Apr-2019
28-May-2019
28-Jun-2019
28-Jul-2019
Any idea?
This code will do what you want. It creates a DateTime object from the start date, and then adds 1 month to the date through the loop:
$loan = 4;
$fixedDateEveryMonth = 28;
$start = new DateTime(date('Y-m-') . $fixedDateEveryMonth);
for ($i = 1; $i <= $loan; $i++) {
$start->add(new DateInterval("P1M"));
echo $start->format('d-M-Y') ."\n";
}
Output:
28-Apr-2019
28-May-2019
28-Jun-2019
28-Jul-2019
Demo on 3v4l.org
I have written a round robin tournament generator in PHP for an online electronic sports league, and I need to calculate the dates for each game in the tournament. Games are played every Thursday and Sunday over the course of many weeks (the number of weeks is dependent on how many teams are participating). Given the starting week and the number of weeks what would be the best way to calculate those dates?
I'm guessing it requires using some combination of DateTime, DateInterval, and DatePeriod; but I am having trouble figuring out how it would be done.
Update:
Apologies for not providing the code before. Here is the solution I had originally come up with. I didn't know if there was a simpler way of doing it. The function was called submitSchedule where the dates were generated.
<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>
The way to achieve this is by using PHP's DateTime classes as you guessed. They are really very useful. I would suggest a little function something like this:-
/**
* #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'));
}
You didn't specify how you would identify the starting week, so I have assumed an ISO week number.
Output:-
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)
See it working.
DateTime manual.
This function will quite happily cope with DST changes, leap years and weeks close to the start and end of the year thanks to the built in magic of the DateTime classes :)
proof or STFU.
Have a look at the strtotime function:
http://www.php.net/manual/en/function.strtotime.php
You could do something like this:
$startDate = "May 15, 2014";
$startDate = strtotime($startDate);
And you could get the start of the Sunday match by simply adding three days:
$nextDate = strtotime("+3 day", $startDate);
Your question is a bit vague, but I think this is what you were asking.
Let's say you have the timestamps of the day of starting week (06:00 AM time)...
Every other date will be 7 days (86400 seconds * 7) in the future.
Let's assume you will run this for 52 weeks (1 year)
$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));
}
At the end of the loop you will have two arrays with all the 52 weeks dates.
I have a table xeon_users_rented, with: clicks0, clicks1, clicks2, clicks3, clicks4, clicks5, clicks6
Each day, clicks0 will increase, and every day at midnight, a cronjob will run, making clicks0 = clicks1 (setting todays clicks, to yesterday clicks), and then set clicks0 to zero.
What I am trying to achieve is I want to make a graph, that shows the sum of clicks0, clicks1 etc., where clicks0 is todays date.
I have the query below:
$data = array();
for ($x = 0; $x <= 6; $x++) {
$date = date("Y/m/d", time() - ($x * 86400));
$queryE = $dbh->prepare("SELECT SUM(clicks$x) FROM xeon_users_rented WHERE user_by=:username");
$queryE->bindParam(":username", $userdata['username']);
$queryE->execute();
$row = $queryE->fetch(PDO::FETCH_ASSOC);
$dates[] = date("Y/m/d", time() - ($x * 86400));
$data[] = ($row['clicks'.$x.''] > 0 ? $row['clicks'.$x.''] : 0);
}
$days = array('Today');
for ($i = 0; $i < 6; $i++) {
$days[$i] = date('d-m', strtotime('-'.($i + 0).' day'));
}
The $days is working perfectly - it will print out today, and the last couple of days.
The $data is not working. It is just printing out:
0,0,0,0,0,0,0
Can someone please help me out here.
The column from your SUM isn't going to be named clicks$x. It will be named something like SUM(clicks1).
Provide an explicit name in the SQL, like
SELECT SUM(clicks$x) as clickSum ...
Then reference it in row as
$row['clickSum']
I am trying to compare times and I'm not entirely sure the best way to handle this.
I have an array of times that is un-able to edit.
array("500", "1100", "1700", "2300");
500 = 5:00am etc...
If it is 6 or 7am, what kind of logic can I run to find out if it is 7am, what time is closer 5am or 10am?
I don't think it's complex, but i'm just trying to figure out a decent solution vs. me trying to hack something together.
Any help or direction would be greatly appreciated!
Let's start with the array you have:
$values = array("500", "1100", "1700", "2300");
What we want is to format it to a valid time string, that is easy, we just insert ":" in the right position. For that I created a function:
function Format($str)
{
$length = strlen($str);
return substr($str, 0, $length - 2).':'.substr($str, $length - 2);
}
Now we can get valid string that we can convert to unix time with strtotime. The problem now is to find the closer to the current time (which we get with time)
So, we can iterate over the array, convert them, calculate the difference with the current time (in absolute value) and pick the one that results in a lower number. Here is the code:
$now = time(); //current time
$best = false;
$bestDiff = 0;
for ($index = 0; $index < count($values); $index++)
{
$diff = abs($now - strtotime(Format($values[$index])));
if ($best === false || $diff < $bestDiff)
{
$best = $index;
$bestDiff = $diff;
}
}
It will leave the index of the closer time in $best and the difference with the moment of the computation in $bestDiff. Please note that this is all asumming that those times are in the same day and local time.
I adapted Theraot's solution to sort the array by the value's distance to the current time:
<?php
$values = array("500", "1100", "1700", "2300");
$now = time();
/**
* Format an integer-string to a date-string
*/
function format($str)
{
$length = strlen($str);
return substr($str, 0, $length - 2).':'.substr($str, $length - 2);
}
/**
* Callback to compare the distance to now for two entries in $values
*/
$compare = function ($timeA, $timeB) use ($now) {
$diffA = abs($now - strtotime(format($timeA)));
$diffB = abs($now - strtotime(format($timeB)));
if ($diffA == $diffB) {
return 0;
}
return ($diffA < $diffB) ? -1 : 1;
};
usort($values, $compare);
print_r($values);
Your desired result is in $values[0] now.
Note that this solution requires php version >= 5.3
the absolute value of the difference between two times
say 07:00 - 05:00 = 02:00, absolute value of 02:00 is still 02:00
07:00 - 10:00 = -03:00, absolute value of -03:00 is 03:00
In PHP you can convert your time-string to seconds using strtotime:
$time_one = strtotime("07:00");
$time_two = strtotime("05:00");
$time_three = strtotime("09:00");
Here's my solution:
// Input data
$values = array("500", "1100", "1700", "2300");
$time = "12:15";
// turns search time to timestamp
$search = strtotime($time);
// turns "500" to "5:00" and so on
$new = preg_replace('/^(\d?\d)(\d\d)$/','\1:\2', $values);
// converts the array to timestamp
$new = array_map('strtotime', $new);
// sorts the array (just in case)
asort($new);
// Some initialization
$distance = $closest = $result = $result_index = NULL;
// The search itself
foreach($new as $idx => $time_stamp)
{
$distance = abs($time_stamp - $search);
if(is_null($closest) OR $closest > $distance)
{
$closest = $distance;
$result_index = $idx;
$result = $time_stamp;
}
}
echo "The closest to $time is ".date('H:i', $result)." ({$values[$result_index]})";
Hey, my problem is as follows,
I am trying to create code where a set of sporting fixtures are created with dates on.
Say I have 8 teams, with 7 rounds of fixtures.
I have generated the fixtures, but want to add a date generation on them.
So if i had 7 rounds, I would put 28 days and it would make each round 4 days from now, 8 days from now, etc.
What would be the best way to go about doing this?
Thanks
This should do what you want and allows for an uneven number of teams. Dates might not be perfect because of the rounding down:
$teams = array("TEAM A","TEAM B","TEAM C","TEAM D","TEAM E", "TEAM F","TEAM G","TEAM H","TEAM I");
$days = 28;
$rounds = count($teams) -1;
//Number of Days Between Fixtures
$daysBetweenFixtures = floor($days / $rounds);
$fixtures = array();
for($i =0; $i < count($teams); $i++) {
//Calculate Date of this round of fixtures
$date = date("D d M Y",mktime(0, 0, 0, date("m") , date("d")+ ($i * $daysBetweenFixtures) , date("Y")));
$hasFixtureToday = array();
for($j=$i; $j<$i+count($teams); $j=$j+2) {
$homeTeam = $teams[$j % count($teams)];
$awayTeam = $teams[($j+1) % count($teams)];
if(!in_array($homeTeam,$hasFixtureToday) && !in_array($awayTeam,$hasFixtureToday)) {
$fixtures[$date][] = "{$homeTeam} vs {$awayTeam}";
$hasFixtureToday[] = $homeTeam;
$hasFixtureToday[] = $awayTeam;
}
}
}
print_r($fixtures);
Example using strtotime() from php-cli:
php > echo date("Y-m-d", strtotime("+4 days"));
2010-05-02
php > echo date("Y-m-d", strtotime("+8 days"));
2010-05-06
php > echo date("Y-m-d", strtotime("+12 days"));
2010-05-10