How to Group Days into Weeks in PHP using diff - php

I am trying to group an index by weeks as opposed to days like the code currently does. My code for displaying the days since the start date (FIRST_DAY_STRING) and time on that day (TIME_SUFFIX) is below. I am having just a bit of trouble converting it to weeks since the start day instead of days.
Thanks for any help in advance. I would also appreciate an explanation of how to do it for months as well as I also need that.
<?php
define("FIRST_DAY_STRING", "2014-3-26");
define("SHIFT_DAYS", 'P2D');
define("TIME_SUFFIX", " 20:30:00 GMT+11:00");
$today = new DateTime();
$first_day = new DateTime(FIRST_DAY_STRING);
$interval = $first_day->diff($today);
$days = $interval->format('%R%a days');
$end_date = $today->add(new DateInterval(SHIFT_DAYS));
$day_number = intval($days) + 1;
$txid = "tx$day_number";
$end_time = $end_date->format('Y-n-j')
$end_time .= TIME_SUFFIX
?>

I did it myself. What I did was divide the inval($days) by 7 and rounded it to the nearest whole number:
$day_number = round(intval($days) / 7 + 1, 0);

Related

DateTime diff returning wrong value

I would like to return the number of days between NOW and some datetime using DateTime object. My dates are:
$now = "2018-03-08 14:00:00";
$last = "2018-02-06 20:00:00";
And I do it like this:
$now = new DateTime();
$last_dt = new DateTime($last);
$difference = $last_dt->diff($now);
$difference->format('%d');
$num_of_days = $difference->d;
For some weird reason, the value of $num_of_days is 1 (instead of like 30)
Anybody knows why please?
Thank you
You need to use DateInterval::$days to get the total in days.
DateInterval::$d is just the number of days but in "grouping form", i.e. 32 days difference will return 2 for DateInterval::$d and 1 for DateInterval::$m.
$last = "2018-04-10 20:00:00";
$now = new DateTime();
$last_dt = new DateTime($last);
$difference = $last_dt->diff($now);
echo "Difference: ".$difference->m." months and ".$difference->d." days, or ".$difference->days." days in total";
Result
Difference: 1 months and 2 days, or 33 days in total
Demo
You can see more in the manual

Function for difference calculation between datetime (months)

my goal is to calculate the number of months between two dates including the starting month.
I am using this function to calculate.
function number_months($date1, $date2){
$begin = new DateTime(date('Y-m-d', strtotime($date1)));
$end = new DateTime(date('Y-m-d', strtotime($date2)));
$diff = $end->diff($begin);
return ($diff->format('%y') * 12) + $diff->format('%m') + 1;
}
In most cases in works fine, but when the function parameters are for example:
$date1 = 2015-11-04 00:00:00
$date2 = 2017-02-01 00:00:00
Function returns:
15
Should be 16. What am I missing? I did reseach here on Stackoverflow, have tried various implementations of provided code, but the problem still ocurs.
Thanks.
11-04 to 12-04 = 1 month.
12-04 to 01-04 = 1 month.
01-04 to 02-01 = 0 month.
Result diff->format('%m') = 2.
($diff->format('%y') * 12) + $diff->format('%m') + 1 = 1*12 + 2 + 1 = 15;
It's true.
The problem is that the user will set the start and end date of project. And I need to create a input for every month the project is going to be set. So i need number 16 in this case.
Thanks to comments i realised that DateTime::diff() works in full units when it comes to years, months and days.
I solved my problem by setting the start and end date to 1st of the month. So now my function returns number of months between two dates including starting and ending month.
function number_months($date1, $date2){
$begin = new DateTime(date('Y-m-d', strtotime($date1)));
$end = new DateTime(date('Y-m-d', strtotime($date2)));
$begin->modify('first day of this month')->setTime(12, 00);
$end->modify('first day of this month')->setTime(12, 00);
$diff = $end->diff($begin);
return ($diff->format('%y') * 12) + $diff->format('%m') + 1;
}

PHP Calculate Number of Weeks Between Dates and Round up to Nearest Week

I am trying to figure out how to calculate the number of weeks between to dates for billing. Billing is weekly so 1+ days = a week and 8+ days = 2 weeks and so on..
So far I have my code working out the number of weeks but it doesnt seems to round up to the nearest week even if it is only a day over (This is what I need)
I hope I have explained it correctly, this is what I have so far.
$strtDate = '2016-03-08';
$endDate = '2016-04-07';
echo $strtDate, $endDate;
$startDateWeekCnt = round(floor( date('d',strtotime($strtDate)) / 7)) ;
$endDateWeekCnt = round(ceil( date('d',strtotime($endDate)) / 7)) ;
$datediff = strtotime(date('Y-m',strtotime($endDate))."-01") - strtotime(date('Y-m',strtotime($strtDate))."-01");
$totalnoOfWeek = round(floor($datediff/(60*60*24)) / 7) + $endDateWeekCnt - $startDateWeekCnt ;
echo $totalnoOfWeek ."\n";
Does anyone know how I could ammend my code to do what I need. In the code I pasted it gives 4 weeks as the answer but It should be five as it is at least 1 day more than 4 weeks.
Thanks so much in advance
You want ceil instead of round.
ceil(abs(strtotime("2016-05-20") - strtotime("2016-05-12")) / 60 / 60 / 24 / 7);
It's far easier working with DateTime objects.
Assuming that the difference is less than a year:
$startDate = new DateTime($strtDate);
$interval = $startDate->diff(new DateTime($endDate));
echo ceil($interval->days / 7);
otherwise (if more than a year)
$startDate = new DateTime($strtDate);
$interval = $startDate->diff(new DateTime($endDate));
echo ceil(($interval->y * 365 + $interval->days) / 7);
although that doesn't take leap years into account

recurring date functions in php

Good Day,
I am trying to create a recurring date system that has the following:
nth day of nth month (2nd day of every 3rd month)
$this_months_friday = strtotime('+3 days +4 months');
the output of that will always be current day + 3 days of the 4th month.
how do I get it to display the nth day of the nth month?
since i also tried
$this_months_friday = strtotime('every 3 days +4 months');
and it did not return any result. Should i stick with strtotime on this one or move to DateTime function of php. though i wont still be able to formulate the proper argument for that kind of date sequence.
Any help would be greatly appreciated.
Thank You.
Probably better off using DateTime with a couple intervals:
$d = new DateTime();
$d->add(new DateInterVal('P' . $days . 'D'))->add('new DateInterVal('P' . $months . 'M'));
not sure what youre two example intervals are wanting.
You want an internval to start in 4 months, which then repeats every 3 days?
That'd be something more like
$d = new DateTime();
$d->add(new DateInterval('P4M')); // jump ahead 4 months immediately
$day3 = new DateInterval('P3D');
for ($i = 0; $i < 100; $i++) {
$d->add($day3); // jump ahead 3 days
... do something with this new date
}
for a basic recurring event, +4 months + 3 days, you'd simply have one interval:
$interval = new DateInteval('P4M3D'); // +4 months +3 days
$date = new DateTime();
while($some_condition) {
$date->add($interval);
do_something();
}
You can do this by saving the values in variables like that :
$day=3;
$month=4;
echo date("d-m-y",strtotime('+'.$day .'days' .'+'.$month.'months'));
Explanation:
7(july)+4 months = 11 month(November)
8 july+ 3 days = 11 july
Output:
11-11-13
NOTE: just for the example I have put the values hard coded, You can make them dynamic.

PHP Find date nearest to a timeline period

So, uh, ok. This might get mathematical, so hope you brought your scientific calculator with you ;)
This is my problem:
Given an initial date (timestamp), time period period (seconds) and today's date (timestamp), I need to find the nearest date which coincides with the period*n plus the original/initial date.
So far, I got some stuff working nicely, such as the amount of "periods" between the initial and final(today's) date, which would be "2" in the demo above:
$initial=strtotime('2 April 1991');
$time=time();
$period=strtotime('+10 years',0);
$periods=round(($time-$initial)/$period);
The next thing I did was:
$range=$periods*$period;
And finally:
echo date('d M Y',$initial+$range);
Which wrote '03 April 2011'. How did it get to 3? (I suspect it's a leap year issue?)
You know that feeling when you're missing something small? I'm feeling it all over me right now....
Ok so if I understood what you are asking, you want to know the next date that will occurs in a given period of time (in your case, every 10 years starting from 2 April 1991, when will be the next date : 2 april 2011).
So, you should take a deeper look at the DateTime class in PHP that is wayyyy better to use for the dates because it is more accurate. You mix it with DateInterval that match exactly what you need :
<?php
$interval = new DateInterval('P10Y'); // 10 years
$initial = new DateTime('1991-04-02');
$now = new DateTime('now');
while ($now->getTimestamp() > $initial->getTimestamp()) {
$initial = $initial->add($interval);
}
echo $initial->format('d M Y'); // should return April 2, 2011 !
?>
Try this out:
$current = $initial = strtotime('2 April 1991');
$time_span = '+10 years';
while ($current < time())
{
$current = strtotime($time_span, $current);
}
echo date('d M Y', $current);
What happened:
+10 years from Year 0 (1970) will include 3 leap years '72, '76 and '80, but from '91 till '11 there are only five leap years '92, '96, '00, '04 and '08. You added that period twice, so because there weren't 6 leap years you got one extra day.
What you need to do:
Ad the period with strtotime one step at a time.
$period = "+10 years";
$newTime = $startingTime;
while(<condition>){
$newTime = strtotime($period, $newTime);
}
As a fix to cx42net's answer:
<?php
$initial = new DateTime('2 April 1991');
$now = new DateTime('now');
$interval = new DateInterval('P10Y');
$curDate = $initial;
while (true) {
$curDate = $curDate->add($interval);
$curDiff = $curDate->diff($now)->days;
if (isset($lastDiff) && ($curDiff > $lastDiff)) {
echo $lastDate->format('d M Y');
break;
} else {
$lastDate = clone $curDate;
$lastDiff = $curDiff;
}
}

Categories