PHP strtotime error when convert some date string to datetime value - php

I have a trouble with strtotime in php.
$j = "2013-10-27";
for ($x = 0; $x < 100; $x++) {
$j = date('Y-m-d', strtotime($j) + 86400);
echo ' '.$j.' <br/>';
}
As the code is self explained, it will add one day to $j and then display to browser.
But when $j = "2013-10-27", it prints just one result ("2013-10-27"). If I change $j to another date, this does work, but also stucks at this date (and some other date).
I have written other code to do this work.
But does anyone know why it fails, or my code is wrong?
Thank you.

This is because you are in a timezone with daylight savings time, and on the 27th October at 1 AM the time reverted to midnight, making it a 25 hour day.
This can be reproduced by setting the timezone:
<?php
date_default_timezone_set('Europe/London');
$j = "2013-10-27";
for ($x = 0; $x < 100; $x++) {
$j = date('Y-m-d', strtotime($j) + 86400);
echo ' '.$j.' <br/>';
}
http://codepad.viper-7.com/uTbNWf

strtotime has too many limitations in my opinion. Use the more recent DateTime lib instead
$j = new DateTime('2013-10-27');
$interval = new DateInterval('P1D');
for ($x = 0; $x < 100; $x++) {
$j->add($interval);
echo $j->format('Y-m-d'), '<br>';
}

Related

Adding month in php?

month adding problem
<?php
$showMonthsQty = 3;
for($i = (1-$showMonthsQty); $i <= 0; $i++)
{
echo $date = date("Y-m-1", strtotime(" +$i months"));
}
?>
when it run's im not geting the desired answer.
OUTPUT
2018-03-1
2018-05-1 <----------error
2018-05-1
but i needed output is :
2018-03-1
2018-04-1
2018-05-1
how can i get this ?pls help!... tnx in advance...:)
You can use DateTime and DateInterval.
$showMonthsQty = 3;
for($i = $showMonthsQty-1; $i >= 0; $i--)
{
$date = new \DateTime(date("Y-m-1")); // First day of the current month
$date->sub(new \DateInterval(sprintf('P%sM', $i))); // Substract $i month (P%dM)
echo $date->format('Y-m-d')."<br />";
}
Output:
2018-03-01
2018-04-01
2018-05-01
Is it what you're looking for ?

php - get sum of clicks for past 7 days

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']

Changing time increments on loop, carring over into next hour when not divisible by 60

Below is the code for a FOR loop that renders out a list of times as so:
...etc...
8:45 am
8:50 am
8:55 am
9:00 am
9:05 am
9:10 am
...etc.
This is a script that runs a five minute interval, and there is currently no issue with this script because it is divisible by 60. However, I need to make it where I can make that time interval whatever amount I want, for instance 9 minutes. I tried changing
for ($j >= 0; $j <= 55; $j+=5) to for ($j >= 0; $j <= 59; $j+=9) desiring an output of:
...etc...
8:36 am
8:45 am
8:54 am
9:03 am
9:12 am
9:21 am
...etc
I WANT IT TO CARRY OVER TO THE NEXT HOUR AND CONTINUE LIKE ABOVE...and notice how the first hour began with :00....and how the next hour began with :03, because 54 plus 9 is 03 speaking in hour terms, that is what I'm looking to do..
However it is outputting only up to the last value before it is less than or equal to 59 and than it quits: i.e
...etc...
8:36 am
8:45 am
8:54 am
---AND STOPS HERE---
Above is how it is echoing.
Below is my code:
$day = date("n/j/y");
$startTime = date(strtotime($day." $coursetee_open_time_slashed"));
///needs to be in "16:00" format
$endTime = date(strtotime($day." $coursetee_close_time_slashed"));
///needs to be in "16:00" format
$timeDiff = round(($endTime - $startTime)/60/60);
$startHour = date("G", $startTime);
$endHour = $startHour + $timeDiff;
for ($i=$startHour; $i <= $endHour; $i++)
{
for ($j >= 0; $j <= 55; $j+=5)
{
$time_pre = $i.":".str_pad($j, 2, '0', STR_PAD_LEFT);
$time = ''.$time_pre .' '.$day.'';
/////////////////////////////
$time_formated_for_cosmetic = date("g:i a", strtotime("$time"));
$time_formated_for_mysql = date("Y-m-d H:i:s", strtotime("$time"));
if (isset($tee_times_from_mysql[$time])) {
$time = '';
} else {
$time = '<option value="' . $time_formated_for_mysql . '">'.$time_formated_for_cosmetic .'</option>';
}
echo $time;
}
}
$increment = 9;
$j = 0;
for ($i=$startHour; $i <= $endHour; $i++)
{
for (; $j < 60; $j += $increment) // $j initialized outside of loop
{
// ...
}
$j -= 60; // Get start minute for next hour
}
You can use timestamp in for loop:
$day = date("n/j/y");
$coursetee_open_time_slashed = "16:00";
$coursetee_close_time_slashed = "18:00";
$startTime = strtotime($day." $coursetee_open_time_slashed"); // timestamp
// needs to be in "16:00" format
$endTime = strtotime($day." $coursetee_close_time_slashed"); // timestamp
// needs to be in "16:00" format
for ($time = $startTime; $time < $endTime; $time += 60 * 5) {
echo date("Y-m-d H:i:s", $time) . "\n";
}

Inserting an image multiple times based on difference between 2 numbers. PHP

working on a script, that calculates the difference between dates retrieved from an API. I want it to then drop in an image as many times as the difference.
$d1 = new DateTime('2012-04-04');
$d2 = new DateTime('2012-03-31');
$interval = $d1->diff($d2);
Ive tried to have a go with a for loop but with no success
for ($i = 0 $i <= $interval; $i++)
{
echo = "<img src=\"test.jpg"/";
}
can you guys see any problems?
I find PHP's DateTime works better when you use the modify() method instead of normal arithmetic.
Assuming you want one image per day:
$d1 = new DateTime('2012-04-04');
$d2 = new DateTime('2012-03-31');
while($d2 <= $d1)
{
echo "<img src=\"test.jpg\">";
$d2->modify("+1 day");
}
This should do it:
<?php
$d1 = strtotime('2012-04-04');
$d2 = strtotime('2012-03-31');
$interval=($d1-$d2)/(3600*24);
for ($i = 0; $i <= $interval; $i++)
{
echo '<img src="test.jpg">';
}
?>

PHP - Is there a simple way to loop between two dates and fill in missing values?

I have 2 dates. Lets say they look like this.
$start = 2010/12/24;
$end = 2012/01/05;
I query the database to look for visits between these two dates. I find some. I then populate an array called stats.
$stats['2010/12/25'] = 50;
$stats['2010/12/31'] = 25;
...
As you can see, there are days missing. I need to fill the missing dates with a value of zero. I was thinking something like this. (I have pulled day / month / year from start and end dates.
for($y=$start_year; $y <= $end_year; $y++) {
for($m=$start_month; $m <=$end_month; $m++) {
for($d=$start_day; $d <= $end_day; $d++) {
This would work fine for the year however the months and days wouldn't work. If the start day is the 15th. Days 1-14 of each subsequent month would be missed. I could have a solution like this then...
for($y=$start_year; $y <= $end_year; $y++) {
for($m=1; $m <13; $m++) {
$total_days = cal_days_in_month(CAL_GREGORIAN, $m, $y) + 1;
for($d=1; $d <= $total_days; $d++) {
I would then need a bunch of if statements making sure starting and end months and days are valid.
Is there a better way of doing this? Or could this even be done in my mysql query?
Just to demonstrate the power of some of PHP's newer interval handling method (mentioned by pgl in his answer):
$startDate = DateTime::createFromFormat("Y/m/d","2010/12/24",new DateTimeZone("Europe/London"));
$endDate = DateTime::createFromFormat("Y/m/d","2012/01/05",new DateTimeZone("Europe/London"));
$periodInterval = new DateInterval( "P1D" ); // 1-day, though can be more sophisticated rule
$period = new DatePeriod( $startDate, $periodInterval, $endDate );
foreach($period as $date){
echo $date->format("Y-m-d") , PHP_EOL;
}
Does require PHP >= 5.3.0
EDIT
If you need to include the actual end date, then you need to add a day to $endDate immediately before the foreach() loop:
$endDate->add( $periodInterval );
EDIT #2
$startDate = new DateTime("2010/12/24",new DateTimeZone("Europe/London"));
$endDate = new DateTime("2012/01/05",new DateTimeZone("Europe/London"));
do {
echo $startDate->format("Y-m-d") , PHP_EOL;
$startDate->modify("+1 day");
} while ($startDate <= $endDate);
For PHP 5.2.0 (or earlier if dateTime objects are enabled)
If you're using PHP5.3 then Mark Baker's answer is the one to use. If (as you say in your comment) you're still on PHP5.2 something like this should help you:
$startdate = strtotime( '2010/12/24' );
$enddate = strtotime( '2012/01/05' );
$loopdate = $startdate;
$datesArray = array();
while( $loopdate <= $enddate ) {
$datesArray[$loopdate] = 0;
$loopdate = strtotime( '+1 day', $loopdate );
}
It will create an array of the unix timestamp of every date between the start and end dates as the index and each value set to zero. You can then overwrite any actual results you have with the correct values.
$start_date = DateTime::createFromFormat('Y/m/d', '2010/12/24');
$end_date = DateTime::createFromFormat('Y/m/d', '2012/01/05');
$current_date = $start_date;
while($current_date <= $end_date) {
$current_date = $current_date->add(new DateInterval('P1D'));
// do your array work here.
}
See DateTime::add() for more information about this.
$i = 1;
while(date("Y/m/d", strtotime(date("Y/m/d", strtotime($start)) . "+ $i days")) < $end) {
... code here ...
$i++;
}
I would calculate the difference between start and end date in days, iterate on that adding a day to the timestamp on each iteration.
$start = strtotime("2010/12/24");
$end = strtotime("2012/01/05");
// start and end are seconds, so I convert it to days
$diff = ($end - $start) / 86400;
for ($i = 1; $i < $diff; $i++) {
// just multiply 86400 and add it to $start
// using strtotime('+1 day' ...) looks nice but is expensive.
// you could also have a cumulative value, but this was quicker
// to type
$date = $start + ($i * 86400);
echo date('r', $date);
}
I have this bit of horrible code saved:
while (($tmptime = strtotime('+' . (int) $d++ . ' days', strtotime($from))) && ($tmptime <= strtotime($to))) // this code makes baby jesus cry
$dates[strftime('%Y-%m-%d', $tmptime)] = 0;
(Set $from and $to to appropriate values.) It may well make you cry, too - but it sort of works.
The proper way to do it is to use DateInterval, of course.

Categories