Date Difference in days in php - php

I have a function to calculate the difference between two dates.
function getDateDifference($to, $from, $in) {
$diff = abs($to - $from);
$years = floor($diff / (365 * 60 * 60 * 24));
$months = floor(($diff - $years * 365 * 60 * 60 * 24) / (30 * 60 * 60 * 24));
$days = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24) / (60 * 60 * 24));
if ($in == "days") {
return $days;
} else if ($in == "months") {
return $months;
} else if ($in == "years") {
return $years;
}
}
For the parameters i first convert the two dates into seconds like this,
checkin = '2012-07-26';
checkout = '2012-07-27';
check_in_date = strtotime(checkin);
check_out_date = strtotime(checkout);
im getting the correct difference when it comes to difference less than one month. But if the difference is more than one month, im always getting the difference as 1. Can someone tell me wat the problem is.

Currently, a month is always 30 * 60 * 60 * 24 sec, aka 30 days.
Your problem is that we're in July, and there are 31 days, not 30. You must take care of number of days per month.

You can make use of the DateTime class.
http://php.net/manual/en/datetime.diff.php
$checkin = new DateTime("2012-07-23");
$checkout = new DateTime("2012-07-27");
$difference = $checkin->diff($checkout);
echo "differrence = " . $difference->format('%R%a days');

Related

calculating difference between two dateTime with my owner class

I want to calculate the days by write two the dates in html form we I did the code bellow I have this problem.
Fatal error: Uncaught ArgumentCountError: Too few arguments to
function Pos_Date::setDate(), 1 passed in
C:\xampp\htdocs\dateTimeZone\index.php on line 40 and exactly 3
expected in C:\xampp\htdocs\dateTimeZone\Date.php:116 Stack trace: #0
C:\xampp\htdocs\dateTimeZone\index.php(40): Pos_Date->setDate('2011,
5, 5') #1 {main} thrown in C:\xampp\htdocs\dateTimeZone\Date.php on
line 116
Note if I put for example 2019, 1 ,1 instead $date1 and 2020, 1
1 instead $date2 after in setDate, it works and echo 365 days left.
in my class on line 116 I have this code
public function setDate($year, $month, $day)
you can see the whole class and my code by this link.
https://drive.google.com/drive/folders/1D406OsQyUEI4MKjSjs3XRWl4aiDyIBAt?usp=sharing
<form action="index.php" method="post">
<input type="text" name="date1">
<input type="text" name="date2">
<input type="submit" name="submit">
</form>
here is php code
$date1 = $_POST['date1'];
$date2 = $_POST['date2'];
if(isset($_POST['date1']) && isset($_POST['date2']) && isset($_POST['submit'])){
try {
$now = new Pos_Date();
$newYear = new Pos_Date();
$now->setDate(2019, 1, 1);
$newYear->setDate($date2);
$diff = $now->dateDiff2($newYear);
$unit = abs($diff) > 1 ? 'days' : 'day';
if ($diff > 0) {
echo "$diff $unit left";
}
} catch (Exception $e) {
echo $e;
}
}
the setDate() method requires the date to be passed in the following format
public DateTime DateTime::setDate ( int $year , int $month , int $day )
So you have to format your date prior to sending it to the method, which can be done using
$date2->format('DD') // for day
$date2->format('Y') // for year
$date2->format('M') // for month
http://php.net/manual/en/datetime.setdate.php
I have make a function that returns difference of two dates in Years,months,days,hours,minutes and seconds. If dates difference in years than it gives only years respectively.
$diff = abs(strtotime($firstime) - strtotime($secondTime));
function timediff($diff) {
$years = floor($diff / (365 * 60 * 60 * 24));
if (empty($years)):
$months = floor(($diff - $years * 365 * 60 * 60 * 24) / (30 * 60 * 60 * 24));
if (empty($months)):
$days = floor(($diff - $years * 365 * 60 * 60 * 24 -
$months * 30 * 60 * 60 * 24) / (60 * 60 * 24));
if (empty($days)):
$hours = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24 - $days * 60 * 60 * 24) / (60 * 60));
if (empty($hours)):
$minutes = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24 - $days * 60 * 60 * 24 - $hours * 60 * 60) / 60);
if (empty($hours)):
$minutes = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24 - $days * 60 * 60 * 24 - $hours * 60 * 60) / 60);
if (empty($minutes)):
$seconds = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24 - $days * 60 * 60 * 24 - $hours * 60 * 60 - $minutes * 60));
endif;
endif;
endif;
endif;
endif;
endif;
I hope this will works better for you.
Thanks,
sandeep

Do action once but only repeat it after x time

So basically, i need to notify a user if:
a) sensor disconnects and there hasn't been an alarm sent in last $send_threshold
b) if alarm sent on same day and greater than $repeat_threshold.
Example values of the variables
$send_threshold = 12 * 60; // 12 min
$repeat_threshold = 2 * 60 * 60 + 45 * 60; // 2 hr 45 min
I'm drawing a complete blank on how to make it happen. The sensors are stateless so there is no way for me to check if a sensor is online, other than to check timestamps of received data that the sensor posted to the api.
/* FUNCTIONS */
function handleDisconnectAlerts($sensor,$dataset,$users,$settings)
{
end($dataset);
$last_timestamp = $dataset[key($dataset)]['timestamp'];
$now = time();
if($now > $last_timestamp && $now - $last_timestamp > $settings['disconnect_alarm'] * 60)
{
$send_threshold = $settings['disconnect_alarm'] * 60;
$repeat_threshold = $settings['disconnect_alarm_repeat_hours'] * 60 * 60 + $settings['disconnect_alarm_repeat_minutes'] * 60;
//not really sure what to do from here.
}
}
Well, i figured it out myself i guess. The initial check covers the intial interval of 60 * $settings['disconnect_alarm']. From there i just needed to check that an alarm hasn't been sent in $repeat_threshold time. Works like a charm.
function handleDisconnectAlerts($sensor,$dataset,$users,$settings)
{
end($dataset);
$last_timestamp = $dataset[key($dataset)]['timestamp'];
$now = time();
if($now > $last_timestamp && $now - $last_timestamp > $settings['disconnect_alarm'] * 60)
{
$repeat_threshold = $settings['disconnect_alarm_repeat_hours'] * 60 * 60 + $settings['disconnect_alarm_repeat_minutes'] * 60;
$n_sent = R::count('sensoralerts',' timestamp >=:time and field_name="disconnect" and sensor_id=:id ',
[':time'=>$repeat_threshold,':id'=>$sensor['id']]
);
if($n_sent == 0){
multiSendDisconnect($users,$sensor);
}
}
}

PHP: What is happening in the round() function?

I get a time in seconds from my database (stored as an integer):
$time = $data["USER_TIME"];
And then i do the following:
$hours = round(($time / 3600), 0);
$minutes = round((($time - ($hours * 3600)) / 60), 0);
$seconds = $time - ($hours * 3600) - ($minutes * 60);
And i create a time string after:
$timeString = formatNumber($hours).":".formatNumber($minutes).":".formatNumber($seconds);
function formatNumber($number) {
if($number < 10) {
return ("0".$number);
} else {
return ("".$number);
}
}
But the results are confusing for me:
10 seconds -> 00:00:10
15 seconds -> 00:00:15
20 seconds -> 00:00:20
25 seconds -> 00:00:25
30 seconds -> 00:01:-30
35 seconds -> 00:01:-25
40 seconds -> 00:01:-20
45 seconds -> 00:01:-15
50 seconds -> 00:01:-10
Can someone explain me what is happening here?
Var_dump $data["USER_TIME"] :
10
15
20
25
30
35
40
45
50
Let's try it with floor. You are using round now, which means everything equal to or above .5 becomes the next integer.
$hours = floor($time / 3600);
$minutes = floor(($time - ($hours * 3600)) / 60);
$seconds = $time - ($hours * 3600) - ($minutes * 60);
You can use the gmdate() function instead of using floor() and round().
echo gmdate("H:i:s", 685);

I have a Broadcast system for in site talking to users,Keeps right time up till 24 hours. After the 24 hour max the time speeds up

$time_ago_op = time() - $comments[$c]['bcttime'];
if ($time_ago_op <= 60) { $comments[$c]['time_ago'] = $time_ago_op . " secs ago."; }
if ($time_ago_op >= 61 && $time_ago_op <= (60 * 60)) { $comments[$c]['time_ago'] = CleanNumber($time_ago_op / 60) . " mins ago."; }
if ($time_ago_op >= (1+(60 * 60)) && $time_ago_op <= (60 * 60 * 24)) { $comments[$c]['time_ago'] = CleanNumber($time_ago_op / (60 * 60)) . " hours ago."; }
if ($time_ago_op >= (1+(60 * 60 * 24)) && $time_ago_op <= (60 * 60 * 24 * 7)) { $comments[$c]['time_ago'] = CleanNumber($time_ago_op / (60 * 60 * 7)) . " days ago."; }
unset($time_ago_op);
After it a user posts it keeps the right time in seconds to minutes and hours, Once it hits 24 hours the time speeds up. For example a post that is 28 hours old says 3 days old and such... I am trying to figure out how to get it to keep the correct time and I am not having any luck.. If anyone can help and point out what I have set wrong it would help out a lot. Thanks
The issue is you are using just pure if blocks. You need to use PHP's if else construct.
Further imagine this scenario. The third if block is at the last nano second before it will trigger the fourth if block. The third will fire off, and then immediately fire the fourth, this can/will cause incorrect calculations.
EDIT
Why don't you just do something like this:
date_default_timezone_set("bcttime"); // whatever the correct time zone is
$server_time= date('G:ia');
$comment_time = $server_time - $comments[$c]['bcttime'];
// display the time with formatting

Calculate total seconds in PHP DateInterval

What is the best way to calculate the total number of seconds between two dates? So far, I've tried something along the lines of:
$delta = $date->diff(new DateTime('now'));
$seconds = $delta->days * 60 * 60 * 24;
However, the days property of the DateInterval object seems to be broken in the current PHP5.3 build (at least on Windows, it always returns the same 6015 value). I also attempted to do it in a way which would fail to preserve number of days in each month (rounds to 30), leap years, etc:
$seconds = ($delta->s)
+ ($delta->i * 60)
+ ($delta->h * 60 * 60)
+ ($delta->d * 60 * 60 * 24)
+ ($delta->m * 60 * 60 * 24 * 30)
+ ($delta->y * 60 * 60 * 24 * 365);
But I'm really not happy with using this half-assed solution.
Could you not compare the time stamps instead?
$now = new DateTime('now');
$diff = $date->getTimestamp() - $now->getTimestamp()
This function allows you to get the total duration in seconds from a DateInterval object
/**
* #param DateInterval $dateInterval
* #return int seconds
*/
function dateIntervalToSeconds($dateInterval)
{
$reference = new DateTimeImmutable;
$endTime = $reference->add($dateInterval);
return $endTime->getTimestamp() - $reference->getTimestamp();
}
DateTime::diff returns a DateInterval object between 2 dates.
The DateInterval object gives all the informations (the number of days, hours, minutes, seconds).
Here's a sample code:
/**
* intervalToSeconds
*
* #param DateInterval $interval
* #return int
*/
function intervalToSeconds(\DateInterval $interval) {
return $interval->days * 86400 + $interval->h * 3600 + $interval->i * 60 + $interval->s;
}
$date_1 = new \DateTime('2021-03-03 05:59:19');
$date_2 = new \DateTime('now');
$interval = $date_1->diff($date_2);
echo intervalToSeconds($interval);
You could do it like this:
$currentTime = time();
$timeInPast = strtotime("2009-01-01 00:00:00");
$differenceInSeconds = $currentTime - $timeInPast;
time() returns the current time in seconds since the epoch time (1970-01-01T00:00:00), and strtotime does the same, but based on a specific date/time you give.
static function getIntervalUnits($interval, $unit)
{
// Day
$total = $interval->format('%a');
if ($unit == TimeZoneCalc::Days)
return $total;
//hour
$total = ($total * 24) + ($interval->h );
if ($unit == TimeZoneCalc::Hours)
return $total;
//min
$total = ($total * 60) + ($interval->i );
if ($unit == TimeZoneCalc::Minutes)
return $total;
//sec
$total = ($total * 60) + ($interval->s );
if ($unit == TimeZoneCalc::Seconds)
return $total;
return false;
}

Categories