I am trying to retrieve the number of days for a PHP interval. When I run the following piece of code on http://sandbox.onlinephpfunctions.com/:
$duration = new \DateInterval('P1Y');
echo $duration->format('%a');
echo "Done";
I get:
(unknown)Done
What am I doing wrong?
The '%a' will return the number of days only when you take a time difference otherwise it will return unknown.
You can use '%d' to get the days but it will also return 0 in the case of new \DateInterval('P1Y') as it does not convert years to days.
One easy way to get the number of days is to create a DateTime at zero time, add the interval to it, and then get the resulting timestamp:
<?php
$duration = new \DateInterval('P1Y');
$intervalInSeconds = (new DateTime())->setTimeStamp(0)->add($duration)->getTimeStamp();
$intervalInDays = $intervalInSeconds/86400;
echo $intervalInDays;
echo " Done";
The problem is here:
$duration->format('%a');
As the manual says, "Total number of days as a result of a DateTime::diff() or (unknown) otherwise".
You need a valid dateInterval object returned by DateTime's diff() method to make the "a" parameter work with DateInterval::format() function:
$now = new DateTime(date('Y-m-d H:i:s'));
$duration = (new DateTime("+1 year"))->diff($now);
echo $duration->format('%a');
Looks like if the DateInterval object is not created by DateTime::diff(), it won't work.
Hope it helps.
You have to create the interval with real dates:
<?php
$interval = date_diff(new DateTime, new DateTime('+1 year'));
echo $interval->format('%a'), PHP_EOL; // 365
if you want something aware of the year or month context, use this, february will return 28 days, leap years will have their additional day
function interval2days($day, $interval) {
$date = clone $day;
$start = $date->getTimeStamp();
$end = $date->add($interval)->getTimeStamp();
return ($end-$start)/86400;
}
Related
I'm really not grasping how dates and times get formatted in PHP for use in mathematical equations. My goal is this;
Get a date and time from the database;
// Get array for times in
$sth = mysqli_query($conn,"SELECT * FROM ledger ORDER BY ID");
$timeins = array();
while($r = mysqli_fetch_assoc($sth)) {
$timeins[] = $r["timein"];
//OR
array_push($timeins, $r['timein']);
}
And then find the distance between the current time and the variable in the array, $timeins[0], and then put the minutes, hours, and days difference in separate simple variables for later use. These variables will be used on their own in if statements to find out if the person has passed certain amounts of time.
edit: the format of the dates being returned from the DB is in the default TIMESTAMP format for MySQL. E.g. 2018-08-06 17:38:37.
It is also possible to perform datetime operations in SQL, to get a difference between two datetime/timestamp values in days, hours, minutes... We can use expressions in the SELECT list, to return the results as columns in the resultset.
Ditching the SELECT * pattern, and specifying an explicit list of expressions that we need returned:
$sql = "
SELECT t.id
, t.timein
, TIMESTAMPDIFF(DAY ,t.timein,NOW()) AS diff_days
, TIMESTAMPDIFF(HOUR ,t.timein,NOW()) AS diff_hours
, TIMESTAMPDIFF(MINUTE ,t.timein,NOW()) AS diff_minute
FROM ledger t
ORDER BY t.id ";
if( $sth = mysqli_query($conn,$sql) ) {
// execution successful
...
} else {
// handle sql error
}
You should use the DateTime class in PHP to do any date manipulation. You can convert a string representation of a MySQL format time to a PHP DateTime object using
$date = DateTime::createFromFormat('Y-m-d H:i:s', $mysqldate);
Also you can create a DateTime object representing the current time using the constructor with no argument:
$now = new DateTime();
To get the difference between two dates as a DateInterval object, use the builtin diff method:
$diff = $now->diff($date);
As a complete example:
$now = new DateTime();
$mysqldate = '2018-04-03 12:30:01';
$date = DateTime::createFromFormat('Y-m-d H:i:s', $mysqldate);
$diff = $now->diff($date);
$diff_days = (int)$diff->format('%a');
$diff_hours = $diff->h;
$diff_minutes = $diff->m;
echo "$diff_days days, $diff_hours hours, $diff_minutes minutes";
Output:
125 days, 9 hours, 4 minutes
Note that you have to use $diff->format('%a') rather than $diff->d to get the days between two dates, as $diff->d will not include the days in any months between the two dates (in this example it will return 3 for today being August 6).
Using the DateTime Class in php is the best way to get accurate results.
$dateNow = new DateTime('now');
$dateIn = DateTime::createFromFormat('d-m-Y H:i:s', $timeins[0]);
$interval = $dateNow->diff($dateIn);
echo $interval->format('%d days, %h hours, %i minutes, %s seconds');
$deltaDays = $interval->d;
$deltaHours = $interval->h;
...
You have to make sure the input format for you DB date is correct, in this case, I assumed d-m-y H:i:s, and then you can output in any format you need as well, as shown in the date docs: http://php.net/manual/en/function.date.php
I want to compare current date's day and month with subscription date's day and month only.
For example:
current date(d-m) = 3-6
And I want compare it with any other d-m
How should I do it in PHP
In my project condition is like birth date in which we don't compare year.
The trick in this is to let the month come first. This way PHP can compare the numbers by highest value. Take a look at the following example:
$aDate = DateTime::createFromFormat('m-d', '05-20');
$bDate = DateTime::createFromFormat('m-d', '06-29');
if ($aDate->format('md') > $bDate->format('md')) {
echo "'aDate' is bigger than 'bDate'";
}
use like
$current_date = date("d-m");
$subscription = "03-06-2016";
$subscription_date = date("d-m", strtotime($subscription));
if($current_date ==$subscription_date)
{
echo "date is equal";
}else
{
echo "date is not equal";
}
If you only need to check if the j-n date is the same as the current date, then you don't need to make more than one function call. Because you are not comparing greater than or less than, the format of your input is unimportant.
Code: (Demo)
$subscription = '29-11';
var_export(date("j-n") === $subscription);
// at the moment, the result is true
j is today's day of the month without any leading zeros and
n is today's month without any leading zeros.
Use DateTime() PHP objects.
Considering you have an array with user info from mysql query result: ($userData['suscriptionDate'])
$today = new DateTime();
$userSuscription = new DateTime($userData['suscriptionDate']);
if ( $today->format('d') == $userSuscription->format('d') && $today->format('m') == $userSuscription->format('m')) {
echo 'Congratulations!!';
}
Use DATE_FORMAT() function to extract part of date:
Ref: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format
SELECT * from table_name WHERE DATE_FORMAT(subscription_date, '%d-%m') = "05-05";
I think, more elegant way to compare, especially when you have a full date with time is diff function of Datetime class:
$d1 = new Datetime();
$d2 = new Datetime('+3 months +2 days +3 hours');
$diff = $d1->diff($d2);
var_dump($diff->d); // 2
var_dump($diff->m); // 2
// or have a comparison as a string
var_dump($diff->format('Difference is in %R%a days'));
// output: Difference is in 63 days
Enjoy! Link to doc
This may help you
$sdate = $row['subscription_date'];
$date1 = date("m-d");
$date2 = date("m-d",strtotime($sdate)) ;
if ($date1 == $date2) {
}
I have on function which passing some parameter the like
everyWeekOn("Mon",11,19,00)
I want to compute the difference between the current day (e.g. 'Fri')
and passed parameter day i.e. Mon.
The output should be:
The difference between Mon and Fri is 3
I tried it like this
$_dt = new DateTime();
error_log('$_dt date'. $_dt->format('d'));
error_log('$_dt year'. $_dt->format('Y'));
error_log('$_dt month'. $_dt->format('m'));
But know I don't know what to do next to get the difference between the two days.
Note that this question is different from How to calculate the difference between two dates using PHP? because I only have a day and not a complete date.
Just implement DateTime class in conjunction with ->diff method:
function everyWeekOn($day) {
$today = new DateTime;
$next = DateTime::createFromFormat('D', $day);
$diff = $next->diff($today);
return "The difference between {$next->format('l')} and {$today->format('l')} is {$diff->days}";
}
echo everyWeekOn('Mon');
$date = new DateTime('2015-01-01 12:00:00');
$difference = $date->diff(new DateTime());
echo $difference->days.' days <br>';
You can find no. of days in two days by using this code
<?php
$today = time();
$chkdate = strtotime("16-04-2015");
$date = $today - $chkdate;
echo floor($date/(60*60*24));
?>
Please use this may this help you
It's the equivalent of the MySQL to_days() function.
Is there a builtin PHP function that does this, or do I need to cobble something together?
You'd need to write your own but it's not hard:
$now = new DateTime();
$zero = new DateTime('0000-00-00'); // -0001-11-30 - Nov 30, 1 BC. Interesting.
$diff = $now->diff($zero);
echo $diff->format('%a days'); // 735728 days
Demo using the literal year zero. You obviously would want to put a valid date in there instead.
$now = new DateTime();
$zero = new DateTime('0001-01-01');
$diff = $now->diff($zero);
echo $diff->format('%a days'); // 735330 days
Demo
As a one liner:
echo (new DateTime())->diff(new DateTime('0001-01-01'))->format('%a days');
As a function:
function toDays($date) {
return (new DateTime())->diff(new DateTime($date))->format('%a');
}
You can use the Julian day count, i.e. with cal_to_js(), see http://www.php.net/manual/de/function.cal-to-jd.php, even if there was no year 0 in the Gregorian calendar.
How to get millisecond between two DateTime objects?
$date = new DateTime();
$date2 = new DateTime("1990-08-07 08:44");
I tried to follow the comment below, but I got an error.
$stime = new DateTime($startTime->format("d-m-Y H:i:s"));
$etime = new DateTime($endTime->format("d-m-Y H:i:s"));
$millisec = $etime->getTimestamp() - $stime->getTimestamp();`
I get the error
Call to undefined method DateTime::getTimestamp()
In the strict sense, you can't.
It's because the smallest unit of time for the DateTime class is a second.
If you need a measurement containing milliseconds then use microtime()
Edit:
On the other hand if you simply want to get the interval in milliseconds between two ISO-8601 datetimes then one possible solution would be
function millisecsBetween($dateOne, $dateTwo, $abs = true) {
$func = $abs ? 'abs' : 'intval';
return $func(strtotime($dateOne) - strtotime($dateTwo)) * 1000;
}
Beware that by default the above function returns absolute difference. If you want to know whether the first date is earlier or not then set the third argument to false.
// Outputs 60000
echo millisecsBetween("2010-10-26 20:30", "2010-10-26 20:31");
// Outputs -60000 indicating that the first argument is an earlier date
echo millisecsBetween("2010-10-26 20:30", "2010-10-26 20:31", false);
On systems where the size of time datatype is 32 bits, such as Windows7 or earlier, millisecsBetween is only good for dates between 1970-01-01 00:00:00 and 2038-01-19 03:14:07 (see Year 2038 problem).
Sorry to digg out an old question, but I've found a way to get the milliseconds timestamp out of a DateTime object:
function dateTimeToMilliseconds(\DateTime $dateTime)
{
$secs = $dateTime->getTimestamp(); // Gets the seconds
$millisecs = $secs*1000; // Converted to milliseconds
$millisecs += $dateTime->format("u")/1000; // Microseconds converted to seconds
return $millisecs;
}
It requires however that your DateTime object contains the microseconds (u in the format):
$date_str = "20:46:00.588";
$date = DateTime::createFromFormat("H:i:s.u", $date_str);
This is working only since PHP 5.2 hence the microseconds support to DateTime has been added then.
With this function, your code would become the following :
$date_str = "1990-08-07 20:46:00.588";
$date1 = DateTime::createFromFormat("Y-m-d H:i:s.u", $date_str);
$msNow = (int)microtime(true)*1000;
echo $msNow - dateTimeToMilliseconds($date1);
DateTime supports microseconds since 5.2.2. This is mentioned in the documentation for the date function, but bears repeating here. You can create a DateTime with fractional seconds and retrieve that value using the 'u' format string.
<?php
// Instantiate a DateTime with microseconds.
$d = new DateTime('2011-01-01T15:03:01.012345Z');
// Output the microseconds.
echo $d->format('u'); // 012345
// Output the date with microseconds.
echo $d->format('Y-m-d\TH:i:s.u'); // 2011-01-01T15:03:01.012345
// Unix Format
echo "<br>d2: ". $d->format('U.u');
function get_data_unix_ms($data){
$d = new DateTime($data);
$new_data = $d->format('U.u');
return $new_data;
}
function get_date_diff_ms($date1, $date2)
{
$d1 = new DateTime($date1);
$new_d1 = $d1->format('U.u');
$d2 = new DateTime($date2);
$new_d2 = $d2->format('U.u');
$diff = abs($new_d1 - $new_d2);
return $diff;
}
https://www.php.net/manual/en/class.datetime.php
Here's a function to do that + tests.
https://gist.github.com/vudaltsov/0bb623b9e2817d6ce359eb88cfbf229d
DateTime dates are only stored as whole seconds. If you still need the number of milliseconds between two DateTime dates, then you can use getTimestamp() to get each time in seconds (then get the difference and turn it into milliseconds):
$seconds_diff = $date2.getTimestamp() - $date.getTimestamp()
$milliseconds_diff = $seconds_diff * 1000