Trouble calculating and displaying days left in PHP - php

I have two variables stored in my database containing the following data:
$date_published = 2012-05-04 00:00:00; //Straight from DB datetime field
$advert_duration = 15;
I want to show an advert for 15 days from the date it was published. To do so I need to work out the time difference.
I have read various places online about calculating time difference and have come up with the below code
In my attempt to work out the equation I can't seem to calculate the differences between $now - the date today, the $date_published and the $advert_duration. I can't get the correct result:
function days_left($date_published, $advert_duration){
$date = new DateTime($date_published);
$now = new DateTime();
$days_elapsed = $date->diff($now)->format("%d");
$days_left = $advert_duration - $days_elapsed;
return $days_left;
}

function getDaysLeft( $date, $duration )
{
// create $date and modify it by $duration
$date = new DateTime( $date );
$date->modify( sprintf( '+%d days', $duration ) );
// calculate the difference
$now = new DateTime();
$daysElapsed = (int) $now->diff( $date )->format( '%a' );
// set to negative value, if modified $date is before $now
if( $date < $now )
{
$daysElapsed = $daysElapsed * -1;
}
return $daysElapsed;
}
var_dump(
getDaysLeft( '2012-05-04 00:00:00', 15 ),
getDaysLeft( '2012-07-04 00:00:00', 15 )
);

If you're fetching your ad from the database, you can simply use a date function to calculate this :
WHERE DATE_SUB(CURDATE(),INTERVAL 15 DAY) >= date
Or you can do this in PHP (you'll get an UNIX timestamp) :
$date = strtotime('+15 days', strtotime($date_published));

Related

How to find range diff 'datetime' and 'time'?

I want to find a range combining both data, that data has datetime and time data types, but datetime must ignore the time.
<?php
function test_duration($start_date, $end_date, $start_time, $end_time) {
$timeInterval = '-';
if(!empty($start_time) && !empty($end_time)) {
$timeStart = new DateTime($start_date->format('Y-m-d').' '.$start_time->format('H:i:s'));
$timeEnd = new DateTime($end_date->format('Y-m-d').' '.$end_time->format('H:i:s'));
$timeInterval = $timeStart->diff($timeEnd)->format('%H:%I:%s');
}
return $timeInterval;
}
$start_date = '2022-09-15 01:01:01';
$end_date = '2022-09-15 02:02:02';
$start_time = '14:48:40';
$end_time = '14:48:45';
echo test_duration($start_date, $end_date, $start_time, $end_time);
?>
so the formula is like this:
range start ==> $start_date (just date) + $start_time
range end ==> $end_date (just date) + $end_time
range start - range end
From the code above it should produce a duration of 5 seconds.
Do you have any solution to fix my code above?
The time can easily be removed from the date with strstr. Then the pure date can be combined with the new time. strtotime is well suited when only seconds are to be determined.
$start_date = '2022-09-15 01:01:01';
$end_date = '2022-09-15 02:02:02';
$start_time = '14:48:40';
$end_time = '14:48:45';
$strStart = strstr($start_date, ' ', true).' '.$start_time;
$strEnd = strstr($end_date, ' ', true).' '.$end_time;
$seconds = strtotime($strEnd) - strtotime($strStart); // int(5)
Time is time, date is date, you shouldn't mix them, so let's say
$start_date = '2022-09-15';
$start_time = '13:00:00';
$end_date = '2022-09-15';
$end_time = '14:00:00';
print strtotime($end_date) + strtotime($end_time) - strtotime($start_date) - strtotime($start_time);
You'll get 3600 seconds
If you know the date is in a fixed format can't you just explode the string on the central space like this?
<?php
function test_duration($start_date, $end_date, $start_time, $end_time) {
$timeInterval = '-';
if(!empty($start_time) && !empty($end_time)) {
$startDateOnly=explode(' ',$start_date)[0];
$endDateOnly=explode(' ', $end_date)[0];
$timeStart = date_create_from_format('Y-m-d H:i:s', $startDateOnly." ".$start_time);
$timeEnd = date_create_from_format('Y-m-d H:i:s', $endDateOnly." ".$end_time);
$timeInterval = $timeStart->diff($timeEnd)->format('%h:%i:%s');
}
return $timeInterval;
}
$start_date = '2022-09-15 01:01:01';
$end_date = '2022-09-15 02:02:02';
$start_time = '14:48:40';
$end_time = '14:48:45';
echo test_duration($start_date, $end_date, $start_time, $end_time);
?>
Your start is quite good, the use of DateTime class is one of the ways to solve your issue. The idea here can be illustrated as follows:
create a DateTime object from the starting date and then alter its time (hours, minutes and seconds) based on the starting time you supply.
do the same thing as the first step but for the ending date so we'll create a DateTime object from the ending date and then alter its time based on the ending time.
return the difference between the two dates in seconds:
to do so we will get the timestamps from both dates
make a simple subtraction of th two timestamps
return the result. We may return the absolute value here to always get a positive number for the case when the starting date is greater than the ending date (not required but that can be seen as an improvement).
Here's a live demo too
$startDate = '2022-09-15 01:01:01';
$endDate = '2022-09-15 02:02:02';
$startTime = '14:48:40';
$endTime = '14:48:45';
function diffInSeconds($startDate, $endDate, $startTime, $endTime)
{
// create a DateTime object based on $startingDate and then alter the time to use the $startingTime instead
$startDate = (new DateTime($startDate))->setTime(
($startTime = explode(':', $startTime))[0],
$startTime[1],
$startTime[2]
);
// create a DateTime object based on $endingDate and then alter the time to use the $endingTime instead
$endDate = (new DateTime($endDate))->setTime(
($endTime = explode(':', $endTime))[0],
$endTime[1],
$endTime[2]
);
// return the difference in seconds which will always be positive thanks to the "abs" function
return abs($endDate->getTimestamp() - $startDate->getTimestamp());
}
// run...
echo diffInSeconds($startDate, $endDate, $startTime, $endTime); // prints: 5
the above is code somehow primitive, it doesn't have any checks on whether the date/times are correct or not also it expects the times to be in the following format "HH:MM:SS".
Anyway, i strongly recommend looking at more modern utilities, especially the Carbon library which makes working with dates and times in PHP a piece of cake.
Learn more about DateTime objects on php.net.

How can I use a variable in a date diff function?

I am using an ACF Field to allow a client to content manage a countdown to their next event I am using JS flip clock on the desktop version but as it isn't responsive, I decided to use date diff to echo out just the number of days for mobile.
The site is currently live at theindustrialproject.co.uk
The code I currently have is this:
<?php
$date1 = date_create(date());
$date2 = date_create(the_field('mobile_date'));
$diff = date_diff($date1,$date2);
$difference = $diff;
if ($difference < 0) { $difference = 0; }
echo '<span class="countdown-mobile">'. floor($difference/60/60/24)."</span><br />";
if ($difference == 1) { echo "<p>Day</p>"; }
else { echo "<p>Days</p>"; }
?>
but it always returns 0. For reference, I pulled the code from here
Without knowing what the function the_field('mobile_date') will return ( either a date or timestamp? ) you might need to alter that particular line below but you should be able to use the DateTime object and format the difference like this
$format='Y-m-d';
$timezone=new DateTimeZone('Europe/London');
/* We need 2 datetime objects - one for now the other for the future date */
$now=new DateTime( date( $format, strtotime('now') ), $timezone );
$target=new DateTime( the_field('mobile_date'), $timezone );
/* Format the difference in days */
$days = $now->diff( $target )->days;
echo "<span class='countdown-mobile'>{$days}</span><br />" . ( $days == 1 ? '<p>Day</p>' : '<p>Days</p>' );

Time To Percent Using PHP

This may sound like a dumb question, but how can I convert the time between two dates to a percent?
I am using this Jquery plugin: http://tinacious.github.io/goalProgress/
The script on page that calculates the percent is:
$('#timerGoal').goalProgress({
goalAmount: 100,
currentAmount: 40,
textBefore: '',
textAfter: '% Completed.'
});
Where it says goalAmount: I'd like that to remain at 100, but where it says currentAmount: 40, I'd somehow like to find the difference in percentage between two days, I know I'd have to set a start date, current date, and end date to find a percentage.
I'm certain part of the code would have to be:
$startDate = '01/01/2015 12:00:00';
$currentDate = date('d/M/Y H:i:s');
$endDate = '02/15/2015 12:00:00';
Finding the difference in two dates is fairly easy, but it's the third date thing I cannot grasp, especially to make it a percentage.
Any ideas?
I was thinking something along the lines of:
[Taken from: How to find the difference in days between two dates ]
$daylen = 60*60*24;
$date1 = '2010-03-29';
$date2 = '2009-07-16';
echo (strtotime($date1)-strtotime($date2))/$daylen;
But everything I read on is two dates not three.
Here is what I've come up with.
It's not calculating percentages yet, but it's something to possibly go off of:
$startDate = '08/01/2015 12:00:00';
$currentDate = date('d/M/Y H:i:s');
$endDate = '09/01/2015 12:00:00';
$startDate =str_replace(array(':', '/', ' '), '', $startDate);
$currentDate =str_replace(array(':', '/', ' '), '', $currentDate);
$endDate =str_replace(array(':', '/', ''), ' ', $endDate);
$mainPercent = $endDate - $startDate;
$actualPercent = $endDate - $currentDate;
$displayPercent = $actualPercent/$mainPercent * 100;
echo $displayPercent;
With todays date being 08/07/2015 I am getting 901.2015119993 which is obviously not a percent, but it's a start.
Working Solution:
$startDate = strtotime('08/01/2015 12:00:00');
$currentDate = time(date('d/M/Y H:i:s'));
$endDate = strtotime('09/15/2015 12:00:00');
$dateDivideBy = $endDate - $startDate;
$dateDivide = $currentDate - $startDate;
$divideProduct = $dateDivide / $dateDivideBy;
$datePercent = round($divideProduct * 100);
echo $datePercent;
With this working code and todays date being 08/07/2015 the value of $datePercent is 14.
The difference between two times, by itself, really can't be converted to a percentage. It's just a period of time. In order to figure out what percentage is complete, you would need to know how long the entire goal is supposed to take (an estimated time, I assume.) Then you can figure out the percentage like this:
ElapsedTime / TotalTime * 100
The total time would be End Date - Start Date, and the elapsed time would be now - start date.
Rather than using string functions to manipulate the dates, it would be better to use DateTime functions.
$startDate = '08/01/2015 12:00:00';
$endDate = '09/01/2015 12:00:00';
$startDate = new DateTime($startDate);
$currentDate = new DateTime(); // defaults to now
$endDate = new DateTime($endDate);
$totalTime = $endDate->diff($startDate)->format('%a');
$elapsedTime = $currentDate->diff($startDate)->format('%a');
// diff returns a DateInterval object; calling its format method
// with %a returns the number of days in the interval
$percent = ($elapsedTime / $totalTime) * 100;
I believe this is your desired outcome, where result is the resulting percent difference between start_actual_time and percent_time:
var percent_time= new Date("01/17/2013 11:20");
var start_actual_time = new Date("01/17/2012 11:20");
var end_actual_time = new Date("01/17/2014 11:20");
var range = end_actual_time - start_actual_time;
var diff = end_actual_time - percent_time;
var result = (diff / range)*100;
In this example, start_actual_time and percent_time are 40% different.

Subtract date variables PHP

Helllo, I have 2 time variables. One I take from the database and another is the current time.
$time_ended = $row['time_ended'];
$time_ended = new DateTime($time_ended);
$now = new DateTime();
What I want is to subtract $now from $time_ended and echo the number of seconds in a result.
Basically the output should be something like 121 or 134. I need this data to create a countdown timer.
Can someone show me the trick?
Thank you for your time.
PHP > 5.3: http://php.net/datetime.diff
PHP < 5.3: http://php.net/strtotime
Use the diff method:
// PHP > 5.3
$diff = $time_ended->diff( $now );
echo $diff->format( '%s' ); // Seconds, with leading zeros
Or if you are not running PHP > 5.3:
// PHP < 5.3
$diff = ( strtotime( $now ) - strtotime( $time_ended ) ) / 3600;
echo date( 's', $diff ); // Seconds, with leading zeros
http://php.net/manual/en/datetime.diff.php
Use the diff method of the DateTime object.
$interval = $time_ended->diff($now);
$diff_seconds = $interval->s; // returns the number of seconds
This will return a DateInterval (http://www.php.net/manual/en/class.dateinterval.php) object. The s property gets the number of seconds of the interval.

Random time and date between 2 date values

I'm trying to write a php script (or line of code) to echo a random time and date between 2 dates, eg
2012-12-24 13:03
which would be between my chosen dates of 1st October 2012 and 1st Jan 2013.
Any ideas how best to do this? Thanks in advance.
Easy :) Just choose 2 random dates, convert to EPOCH, and random between these 2 values :)
EPOCH - The time since 1/1/1970, in seconds.
You can use the strtotime() function to make date-strings turn into epoch time, and the date() function to make it the other way back.
function rand_date($min_date, $max_date) {
/* Gets 2 dates as string, earlier and later date.
Returns date in between them.
*/
$min_epoch = strtotime($min_date);
$max_epoch = strtotime($max_date);
$rand_epoch = rand($min_epoch, $max_epoch);
return date('Y-m-d H:i:s', $rand_epoch);
}
You probably want to define a resolution, for example one minute, or three minutes or 15 seconds or one and a half day or what not. The randomness should be applied on the whole period, I've choosen one minute here for exemplary purposes (there are 132480 minutes in your period).
$start = new Datetime('1st October 2012');
$end = new Datetime('1st Jan 2013');
$interval = new DateInterval('PT1M'); // Resolution: 1 Minute
$period = new DatePeriod($start, $interval, $end);
$random = new RandomIterator($period);
list($result) = iterator_to_array($random, false) ? : [null];
This for example gives:
class DateTime#7 (3) {
public $date =>
string(19) "2012-10-16 02:06:00"
public $timezone_type =>
int(3)
public $timezone =>
string(13) "Europe/Berlin"
}
You can find the RandomIterator here. Without it, it will take a little longer (ca. 1.5 the number of iterations compared to the example above) using:
$count = iterator_count($period);
$random = rand(1, $count);
$limited = new LimitIterator(new IteratorIterator($period), $random - 1, 1);
$limited->rewind();
$result = $limited->current();
I also tried with seconds, but that would take quite long. You probably want first to find a random day (92 days), and then some random time in it.
Also I've run some tests and I could not find any benefit in using DatePeriod so far as long as you're on common resolutions like seconds:
$start = new Datetime('1st October 2012');
$end = new Datetime('1st Jan 2013');
$random = new DateTime('#' . mt_rand($start->getTimestamp(), $end->getTimestamp()));
or minutes:
/**
* #param DateTime $start
* #param DateTime $end
* #param int|DateInterval $resolution in Seconds or as DateInterval
* #return DateTime
*/
$randomTime = function (DateTime $start, DateTime $end, $resolution = 1) {
if ($resolution instanceof DateInterval) {
$interval = $resolution;
$resolution = ($interval->m * 2.62974e6 + $interval->d) * 86400 + $interval->h * 60 + $interval->s;
}
$startValue = floor($start->getTimestamp() / $resolution);
$endValue = ceil($end->getTimestamp() / $resolution);
$random = mt_rand($startValue, $endValue) * $resolution;
return new DateTime('#' . $random);
};
$random = $randomTime($start, $end, 60);
Assuming you want to include October 1st, but not include Jan 1st...
$start = strtotime("2012-10-01 00:00:00");
$end = strtotime("2012-12-31 23:59:59");
$randomDate = date("Y-m-d H:i:s", rand($start, $end));
echo $randomDate;
so crazy it just may worK
function randomDate($start_date, $end_date)
{
//make timetamps
$min = strtotime($start_date);
$max = strtotime($end_date);
//random date
$rand_date = rand($min, $max);
//format it
return date('Y-m-d H:i:s', $rand_date);
}
Here's some code to accomplish this:
$randDate=date('Y-m-d', mt_rand(strtotime('2012-10-01'), strtotime('2013-01-01')));
Okay, here's something
$date_start = strtotime('1 October 2012');
$date_end = strtotime('1 January 2013');
$rand_date = rand($date_start, $date_end);
echo(date('d.m.Y H:i', $rand_date));

Categories