Months from 2 unixtimestamps - php

I have 2 timestamps from 2 dates: 01/2012 and 02/2013. The difference between these timestamps is 31795200. The function i've used is:
function unixTimeStampInMonths($timestamp){
$elapsed_minutes = ($timestamp / 60);
$elapsed_hours = ($elapsed_minutes / 60);
$elapsed_days = ($elapsed_hours / 24);
$elapsed_months = floor($elapsed_days / 30);
return $elapsed_months;
}
But there is a problem, the months are rounded to 30 days. What's the best way of calculating the months difference between them?
LE:
The solution suggested by a friend is:
// arguments format: 05/2010
function monthDifferenceBetween2Dates($first, $second){
$expl1 = explode('/', $first);
$expl2 = explode('/', $second);
$months_in_years = ($expl2[1] - $expl1[1] - 1) * 12;
$first_months = 12 - $expl1[0];
$second_months = $expl2[0];
return $months_in_years + $first_months + $second_months;
}
i'm gonna use this. thanks #nickb

Use PHP's DateTime class instead of UNIX timestamps:
$start = DateTime::createFromFormat( 'm/d/Y', '01/01/2012');
$end = DateTime::createFromFormat( 'm/d/Y', '02/01/2013');
$diff = $start->diff( $end);
var_dump( $diff);
Will output:
object(DateInterval)#3 (8) {
["y"]=>
int(1)
["m"]=>
int(1)
["d"]=>
int(0)
["h"]=>
int(0)
["i"]=>
int(0)
["s"]=>
int(0)
["invert"]=>
int(0)
["days"]=>
int(397)
}
So, to calculate total months, we can do:
$months = $diff->y * 12 + $diff->m;
Which will print 13. Demo

Related

PHP Date + days

I got something like this in MyBB and I want add 5 days to date ($datetime1) with one should be stored in $nowPlus5D.
Moreover display in $leeft variable how much days, hours, minutes left. difference between (day bought + 5days ) - datenow
define("IN_MYBB", 1);
require_once "global.php";
$data_zakupu = $db->query("
SELECT timestamp
FROM ".TABLE_PREFIX."subs
WHERE txn_id <> '' AND uid=".$mybb->user['uid']." ORDER BY lid DESC LIMIT 1;
");
$dat = $db->fetch_field($data_zakupu,"timestamp");
$date_buy = date('d-m-Y H:i:s', $dat); // added h:i:s
// Total bought
echo '<br><hr>';
echo 'Bought date - ' . $date_buy;
echo '<br>';
$datetime2 = new DateTime('now');
$datetime1 = new DateTime($date_buy);
$interval = $datetime1->diff($datetime2);
$nowPlus5D = $datetime1->add(new DateInterval('P5D'));
echo '<hr><br>';
echo 'Expiration date - ' . $nowPlus5D->format('%a days, %h hours, %i, minutes');
echo '<br>';
$leeft = $nowPlus5D->diff($datetime1);
var_dump($leeft);
echo '<br>';
echo $left->format('%a days, %h hours, %i, minutes');
and I got that
Bought date - 20-12-2018 18:20:48
Expiration date - %pm 25pm1848, %06 062018000000Tue, 25 Dec 2018 18:20:48 +010048, %20, 12201200000031Europe/Warsaw48
object(DateInterval)#14 (15) { ["y"]=> int(0) ["m"]=> int(0) ["d"]=> int(0) ["h"]=> int(0) ["i"]=> int(0) ["s"]=> int(0) ["weekday"]=> int(0) ["weekday_behavior"]=> int(0) ["first_last_day_of"]=> int(0) ["invert"]=> int(0) ["days"]=> int(0) ["special_type"]=> int(0) ["special_amount"]=> int(0) ["have_weekday_relative"]=> int(0) ["have_special_relative"]=> int(0) }
Fatal error: Call to a member function format() on integer in /stackoverflow.php on line 42
Your main issue is you are confusing a couple objects. Specifically DateInterval with DateTime. Formatting is one thing that differs.
<?php
$date_buy = '2018-12-15 10:05:22';
$datetime2 = new DateTime('now');
$datetime1 = new DateTime($date_buy);
$interval = $datetime1->diff($datetime2);
$nowPlus5D = $datetime1->add(new DateInterval('P5D'));
//THIS IS A DATETIME OBJECT, NOT AN INTERVAL! NOTE FORMAT `Y-m-d H:i:s`
echo 'Expiration date - ' . $nowPlus5D->format('d \d\a\y\s, H \h\o\u\r\s, i \m\i\n\u\t\e\s');
var_dump($nowPlus5D);
var_dump($datetime1);
// ^ Notice those are the same? A result of `$nowPlus5D = $datetime1->add(new DateInterval('P5D'));`
// and Intervals then are of course zeros...
$left = $nowPlus5D->diff($datetime1);
echo '<br>';
echo $left->format('%a days, %h hours, %i, minutes');
// could do this...
$left = $nowPlus5D->diff(new \DateTime);
echo $left->format('%a days, %h hours, %i, minutes');
Anyway, think your main confusion was over the two object types. Imagine you can take it from here.

php issue with date_diff

I'm trying to figure out the number of months between two dates, the dates hypothetically lets say are between 2018-08-27 and 2018-10-10. What i want is a function based on those dates to return a difference of 3 months, 08,09,10. I have the following function, but it only seems to output 1 month;
public function getGraphMonthsCount(){
$now = '2018-08-27';
$then = '2018-10-10';
$newNow = new DateTime($now);
$newThen = new DateTime($then);
$result = $newNow->diff($newThen)->m;
return $result;
}
this return a value of 1.
this is what the diff function outputs without the ->m param
object(DateInterval)#157 (15) {
["y"]=>
int(0)
["m"]=>
int(1)
["d"]=>
int(13)
["h"]=>
int(0)
["i"]=>
int(0)
["s"]=>
int(0)
["weekday"]=>
int(0)
["weekday_behavior"]=>
int(0)
["first_last_day_of"]=>
int(0)
["invert"]=>
int(0)
["days"]=>
int(44)
["special_type"]=>
int(0)
["special_amount"]=>
int(0)
["have_weekday_relative"]=>
int(0)
["have_special_relative"]=>
int(0)
}
I don't know why it's providing only 13 'd' and 1 'm', but if you look further into the obj you can see it does have the correct amount of 'days'
Is there a better way of doing this?
What i want is a function based on those dates to return a difference of 3 months
You can try something like this:
$newNow = new DateTime($now);
$newNow = $newNow->modify('first day of this month');
$newThen = new DateTime($then);
$newThen = $newThen->modify('first day of next month');
$result = $newNow->diff($newThen)->m;
Test results:
$now = '2018-08-27';
$then = '2018-10-10';
// 3
$now = '2018-08-10';
$then = '2018-08-27';
// 1

Increment the day value from current day

For example, in my case, i already has this value of array.....
array(1) {
[1]=>
array(1120) {
["2006-02-25"]=>
array(1) {
[0]=>
int(33)
}
["2006-02-20"]=>
array(1) {
[0]=>
int(38)
}
["2006-02-28"]=>
array(1) {
[0]=>
int(46)
}
that result I've got this code
$explodeEndDate = explode(" ",$adEndDate);
$explodeStartDate = explode(" ", $adStartDate);
$StartDate = $explodeStartDate[0];
$NewStartDate = strtotime("$explodeStartDate[0]");
$NewEndDate = strtotime("$explodeEndDate[0]");
$timeDiff = abs($NewEndDate - $NewStartDate);
// 86400 seconds in one day
$NumberDays = $timeDiff/86400;
//convert into int
$NumberDays = intval($NumberDays);
if(array_key_exists($NumberDays, $array[$itemType]) == false){
$array[$itemType][$StartDate] =[$NumberDays];
}
}
what I wanted to achieve is, in the "$StartDate" value which is for example ["2006-02-28"] , I wanted to plus it with the value of it. If we referring back to the figure above for example is
["2006-02-25"]=>
array(1) {
[0]=>
int(33)
so 2006-02-25 is the plus by 33 and the result is 2006-04-01. and after that, i wanted to make the date within that range
If you want to add date so here you go:
Months:
<?php
$date = date('Y-m-d', strtotime("+33 months", strtotime('2006-02-25')));
var_dump($date)
?>
Demo.
Days:
<?php
$date = date('Y-m-d', strtotime("+33 days", strtotime('2006-02-25')));
var_dump($date)
?>
Demo

How to account for GMT offset when converting date timestamp to relative time

I have timestamps in the following format: 2013-10-19 18:47:30
I am using this to convert to relative (x minutes, hours, days ago) time but it returns nothing for the most recent users, I assume because my system time is GMT -3 hours so it is interpreting it as a time in the future. If that is the case, how can I take the users GMT offset into account in the result?
$time = strtotime('2013-04-28 17:25:43');
echo 'event happened '.humanTiming($time).' ago';
function humanTiming ($time)
{
$time = time() - $time; // to get the time since that moment
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
}
}
$eventTimeString = '2013-04-28 17:25:43';
$timezone = new DateTimeZone("Etc/GMT+3"); // Same as GMT-3, here you should use the users's timezone
$eventTime = new DateTime($eventTimeString , $timezone);
$diff = $eventTime->diff(new DateTime()); // Compare with
The $diff variable now has number of seconds, months, days etc. since $eventTime
object(DateInterval)#4 (15) {
["y"]=>
int(0)
["m"]=>
int(7)
["d"]=>
int(18)
["h"]=>
int(17)
["i"]=>
int(35)
["s"]=>
int(38)
["weekday"]=>
int(0)
["weekday_behavior"]=>
int(0)
["first_last_day_of"]=>
int(0)
["invert"]=>
int(0)
["days"]=>
int(232)
["special_type"]=>
int(0)
["special_amount"]=>
int(0)
["have_weekday_relative"]=>
int(0)
["have_special_relative"]=>
int(0)
}
Here is a rewrite of your method that will be more reliable/accurate:
function humanTiming($time){
$timezone=new DateTimeZone("Australia/Melbourne"); // declare whatever your user's timezone is
$time=new DateTime($time,$timezone); // input your datetime
$now=new DateTime("now",$timezone); // get current datetime
if($time>$now){
return "event hasn't happened yet";
}elseif($time==$now){
return "event is happening";
}
$diff=(array)$time->diff($now); // get time between now and $time, cast as array
$labels=array("y"=>"year","m"=>"month","d"=>"day","h"=>"hour","i"=>"minute","s"=>"second");
$readable=""; // declare as empty string
// filter the $diff array to only the desired elements and loop
foreach(array_intersect_key($diff,$labels) as $k=>$v){
if($v>0){ // only add non-zero values to $readable
$readable.=($readable!=""?", ":"")."$v {$labels[$k]}".($v>1?"s":"");
// use comma-space as glue | show value | show unit | pluralize when necessary
}
}
return "event happened $readable ago";
}
echo humanTiming('2013-04-28 17:25:43');
// event happened 3 years, 10 months, 23 days, 8 hours, 33 minutes, 59 seconds ago

PHP Date difference

i've the following code:
$dStart = new DateTime('2013-03-15');
$dEnd = new DateTime('2013-04-01');
$dDiff = $dStart->diff($dEnd);
echo $dDiff->days;
I don't know why i'm getting 6015 as result.
Try like
$dStart = strtotime('2013-03-15');
$dEnd = strtotime('2013-04-01');
$dDiff = $dEnd - $dStart;
echo date('H:i:s',$dDiff);
or as per your code try with
$dDiff = $dStart->diff($dEnd);
$date->format('d',$dDiff);
echo $dDiff->days;
if you want diff in days try with this also
echo floor($dDiff/(60*60*24));
Try this-
$dStart = new DateTime('2013-03-15');
$dEnd = new DateTime('2013-04-01');
$dDiff = $dStart->diff($dEnd);
echo $dDiff->format('%d days')
Check PHP
Please check demo link
use this
$datetime1 = date_create('2013-03-15');
$datetime2 = date_create('2013-04-01');
$interval = date_diff($datetime1, $datetime2);
echo $interval->format('%R%a days');
I prefer something like:
function days_diff($first_date, $second_date)
{
$later = new DateTime($second_date);
$then = new DateTime($first_date);
return $later->diff($then)->format('a');
}
I got the same 6015 days on PHP 5.3.0 and found the solution using var_dump().
My exact code is here:
$timestring = "Thu, 13 Jun 2013 14:05:59 GMT";
date_default_timezone_set('GMT');
$date = DateTime::createFromFormat('D, d M Y G:i:s T', $timeString);
$nowdate = new DateTime("now");
$interval = $date->diff($nowdate);
Now if I do a var_dump($interval), the result is:
object(DateInterval)#5 (8) {
["y"]=>
int(0)
["m"]=>
int(0)
["d"]=>
int(0)
["h"]=>
int(19)
["i"]=>
int(45)
["s"]=>
int(33)
["invert"]=>
int(0)
["days"]=>
int(6015)
}
So the hours (h), minutes(i) and seconds (s) are set correctly but there is another property days which remains constant at 6015 and this is what others are getting as a bug. Well, I can't understand where it is getting this value. Again, as per the PHP manual for DateInterval at http://www.php.net/manual/en/class.dateinterval.php, I tried accessing them as properties of an object and things went absolutely fine.
Hence, I get exact result by:
echo (string) $interval->d." days ago";

Categories