I'm trying to get the date every 1 year or any variable interval between two dates. My dates examples are as follows. It just seems to run forever and I cant make it work and it doesn't print anything out at the end.
$currentDate = '2014-04-15';
$endDate = '2018-04-15';
$reminder = '+1 year';
$dateArray = array();
while($currentDate <= $endDate){
$currentDate = date('Y-m-d', strtotime($reminder, strtotime($currentDate)));
array_push($dateArray, $currentDate);
}
print_r($dateArray);
please change
$dateArray = array_push($dateArray, $currentDate);
to
array_push($dateArray, $currentDate);
Because array_push, returns boolean and next time, you call this function, it tries to store string in the int/boolean type and cause error.
You can use the DateInterval class and DateTime::Add() method:
$begin_date = DateTime::createFromFormat('Y-m-d', '2014-04-15');
$end_date = DateTime::createFromFormat('Y-m-d', '2018-04-15');
$res_array = array();
while ($begin_date < $end_date)
{
$begin_date->Add(DateInterval::createFromDateString('1 year'));
$res_array[] = clone($begin_date);
}
echo ("<pre>"); print_r($res_array); echo ("</pre>");
Thats the Object oriented style.
Related
I am calculated the date in 6 months time like this...
$date = new DateTime('01/02/2019');
$date->add(new DateInterval('P6M'));
echo $date->format('d/m/Y') . "\n";
This is working as far as I can tell, does anybody know of a way to get it to output an array of dates in this new period?
Does DateTime have anything built in?
You need to loop through all the dates, as there is no native function to do this.
You can create a loop that would append each date to an array, and increment the date until it reaches the end-date.
function get_interval($startDate, $endDate) {
$result = [];
while ($startDate < $endDate) {
$currentDate = (clone $startDate);
$result[] = $currentDate;
$startDate->modify("+1 day");
}
return $result;
}
$date = new DateTime('01/02/2019');
$enddate = (clone $date)->add(new DateInterval('P6M')); // Note that the object is cloned
// Otherwise we modify the original $date
print_r(get_interval($date, $enddate));
Live demo at https://3v4l.org/aLf5o
i need to get immediate date like if i select date is 05 then output will be 2017-07-05 cause select date already passed
if i select 12 then output will be 2017-06-12 cause this date future date
final if i select previous date of current month then output will be next month same date and if i select future date of current month then output will be same month
i have tired but not working this
$today = date("Y-m-d");
$next_payment_date = date('Y-m-d', strtotime('+1 month', $today));
or
$time = time();
date("Y-m-d", mktime(0,0,0,date("n", $time),date("j",$time)- 1 ,date("Y", $time)));
thanks in your advance
One more option:
https://3v4l.org/Me2Kh
$input = 12;
$day = date("d");
if ($input > $day){
$date = date("Y-m-"). str_pad($input,2,"0", STR_PAD_LEFT);
}else{
$date = date("Y-m-",strtotime("+1 month")). str_pad($input,2,"0", STR_PAD_LEFT);
}
echo $date;
I use str_pad to keep two digit day number.
Try this -
<?php
$day = '05';
$today = date('Y-m-d');
$supplied = date('Y-m-'.$day);
if($today>$supplied){
$final = date('Y-m-d', strtotime("+1 months", strtotime($supplied)));
}
else{
$final = $supplied;
}
echo $today;
echo '<br />';
echo $supplied;
echo '<br />';
echo $final;
What I'm doing here -
Comparing the current and supplied date
Based on comparison, if supplied date is smaller, I'm adding 1 month else dislpaying the supplied date.
use this,
$today = date('Y-m-d');
$nextDate = date('Y-m-d', strtotime('+1 month'));
or $nextDate = date('Y-m-d', strtotime('+1 month', strtotime($today));
I think this may help.
I would consider using DateTime and it's add method for a DateInterval.
$date = new \DateTime('now', new \DateTimeZone('America/New_York'));
$interval = new \DateInterval('P1M');
$date->add($interval);
Here are the supported DateTimeZone values. Make sure to set that to the applicable time zone.
Edit:
DateTime is mutable, so please keep that in mind.
Try this code :
<?php
$selected_date = '2017-06-05';
$current = date('Y-m-d');
//echo $current;
if($selected_date < $current)
{
$newDate = date('Y-m-d',strtotime($selected_date."+1 month"));
echo $newDate; // gives 2017-07-05
}else if($selected_date > $current)
{
$newDate = $current;
echo $newDate; // gives 2017-06-07
}
?>
From what you described in the points at beginning of the question, you could achieve it this way:
$selectedDate = new DateTime('2016-06-05 00:00:00');
$now = new DateTime('now');
$now->setTime(0, 0, 0);
if ($selectedDate < $now) { // Selected date is in past
// Set month and year to current
$selectedDate->setDate(
date('Y'),
date('m'),
$selectedDate->format('d')
);
// Add 1 month
$selectedDate->add(new DateInterval('P1M'));
}
// If selected date is current or in future we do nothing
echo $selectedDate->format('Y-m-d');
For input 2017-06-05 it will return 2017-07-05 as expected, and for current or future date will return the date that was selected. Works also for any past date like 2016-04-05
i got 3 different Datetimes. $start_date and $end_date are the given range of dates i work with. What i need is to find the $date_from_user in this range, what is not the problem, i found plenty of solutions for that, like this SO answer.
But what i need is then to tell what exact day the $date_from_user is in the given Daterange.
So taken from the example below the expected result would be 5.
$start_date = '2009-09-05';
$end_date = '2009-09-17';
$date_from_user = '2009-09-10';
How can i get the number of the day from the range?
I thought for myself about an for loop to compare the date, but that would be problematic if the Daterange is larger than a month.
$date_from = '2014-5-25';
$date_from = strtotime($date_from);
$date_to = '2014-6-4';
$date_to = strtotime($date_to);
for ($i = $date_from; $i <= $date_to; $i += 86400) {
$dates[] = date("Y-n-j", $i);
}
return $dates
Try the above
You should be using the DateTime classes for date calculations. They are very flexible and will take into account DST, timezones and leap years. I am at a loss as to why people are still using strtotime().
Effectively, all you need to do is count the number of days from the start of the range to the user provided date after checking that user has provided a date within the required range.
A function similar to this would work for you:-
function getDayNumberInRange($start, $end, $dayToFind)
{
$format = 'Y-m-d';
$startDate = \DateTime::createFromFormat($format, $start);
$endDate = \DateTime::createFromFormat($format, $end);
$toFind = \DateTime::createFromFormat($format, $dayToFind);
if($toFind < $startDate || $toFind > $endDate){
throw new InvalidArgumentException('The date to find must be between the start and end of the range.');
}
return $toFind->diff($startDate)->days;
}
$start_date = '2009-09-05';
$end_date = '2009-09-17';
$date_from_user = '2009-09-10';
echo getDayNumberInRange($start_date, $end_date, $date_from_user); // 5
I am using this code to add a week to a date:
$date1 = "2009-10-11";
$d = new DateTime($date1);
$d->modify( '+1 week' );
echo $d->format( 'Y m d' ), "\n";
It works fine good but want to add this functionality:
$startDate = "2009-10-11";
$endDate = "2010-01-20";
And want to create an array that holds ALL the +1 weeks IN BETWEEN these dates. How can i do this?
Here is one way of doing it:
$startDate = "2009-10-11";
$endDate = "2010-01-20";
$dates = array();
$temp = strtotime($startDate);
do {
$dates[] = date("Y-m-d", $temp);
$temp = strtotime("+1 week", $temp);
} while ($temp < strtotime($endDate));
print_r($dates);
You can see a demo here
Dates can be converted to timestamps. Timestamps are great for being compared because they basically just integers.
What I would do as a quick'n'dirty solution is to convert both your dates to timestamps and then design a loop like this (pseudo-code) :
timestamp = start_timestamp
WHILE timestamp < end_timestamp
timestamp = timestamp + 1 week
dates[] = timestamp
END WHILE
Let's assume I have two dates in variables, like
$date1 = "2009-09-01";
$date2 = "2010-05-01";
I need to get the count of months between $date2 and $date1($date2 >= $date1). I.e. i need to get 8.
Is there a way to get it by using date function, or I have to explode my strings and do required calculations?
Thanks.
For PHP >= 5.3
$d1 = new DateTime("2009-09-01");
$d2 = new DateTime("2010-05-01");
var_dump($d1->diff($d2)->m); // int(4)
var_dump($d1->diff($d2)->m + ($d1->diff($d2)->y*12)); // int(8)
DateTime::diff returns a DateInterval object
If you don't run with PHP 5.3 or higher, I guess you'll have to use unix timestamps :
$d1 = "2009-09-01";
$d2 = "2010-05-01";
echo (int)abs((strtotime($d1) - strtotime($d2))/(60*60*24*30)); // 8
But it's not very precise (there isn't always 30 days per month).
Last thing : if those dates come from your database, then use your DBMS to do this job, not PHP.
Edit: This code should be more precise if you can't use DateTime::diff or your RDBMS :
$d1 = strtotime("2009-09-01");
$d2 = strtotime("2010-05-01");
$min_date = min($d1, $d2);
$max_date = max($d1, $d2);
$i = 0;
while (($min_date = strtotime("+1 MONTH", $min_date)) <= $max_date) {
$i++;
}
echo $i; // 8
Or, if you want the procedural style:
$date1 = new DateTime("2009-09-01");
$date2 = new DateTime("2010-05-01");
$interval = date_diff($date1, $date2);
echo $interval->m + ($interval->y * 12) . ' months';
UPDATE: Added the bit of code to account for the years.
Or a simple calculation would give :
$numberOfMonths = abs((date('Y', $endDate) - date('Y', $startDate))*12 + (date('m', $endDate) - date('m', $startDate)))+1;
Accurate and works in all cases.
This is another way to get the number of months between two dates:
// Set dates
$dateIni = '2014-07-01';
$dateFin = '2016-07-01';
// Get year and month of initial date (From)
$yearIni = date("Y", strtotime($dateIni));
$monthIni = date("m", strtotime($dateIni));
// Get year an month of finish date (To)
$yearFin = date("Y", strtotime($dateFin));
$monthFin = date("m", strtotime($dateFin));
// Checking if both dates are some year
if ($yearIni == $yearFin) {
$numberOfMonths = ($monthFin-$monthIni) + 1;
} else {
$numberOfMonths = ((($yearFin - $yearIni) * 12) - $monthIni) + 1 + $monthFin;
}
I use this:
$d1 = new DateTime("2009-09-01");
$d2 = new DateTime("2010-09-01");
$months = 0;
$d1->add(new \DateInterval('P1M'));
while ($d1 <= $d2){
$months ++;
$d1->add(new \DateInterval('P1M'));
}
print_r($months);
Using DateTime, this will give you a more accurate solution for any amount of months:
$d1 = new DateTime("2011-05-14");
$d2 = new DateTime();
$d3 = $d1->diff($d2);
$d4 = ($d3->y*12)+$d3->m;
echo $d4;
You would still need to handle the leftover days $d3->d if your real world problem is not as simple and cut and dry as the original question where both dates are on the first of the month.
This is a simple method I wrote in my class to count the number of months involved into two given dates :
public function nb_mois($date1, $date2)
{
$begin = new DateTime( $date1 );
$end = new DateTime( $date2 );
$end = $end->modify( '+1 month' );
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($begin, $interval, $end);
$counter = 0;
foreach($period as $dt) {
$counter++;
}
return $counter;
}
In case the dates are part of a resultset from a mySQL query, it is much easier to use the TIMESTAMPDIFF function for your date calculations and you can specify return units eg. Select TIMESTAMPDIFF(MONTH, start_date, end_date)months_diff from table_name
strtotime is not very precise, it makes an approximate count, it does not take into account the actual days of the month.
it's better to bring the dates to a day that is always present in every month.
$date1 = "2009-09-01";
$date2 = "2010-05-01";
$d1 = mktime(0, 0, 1, date('m', strtotime($date1)), 1, date('Y', strtotime($date1)));
$d2 = mktime(0, 0, 1, date('m', strtotime($date2)), 1, date('Y', strtotime($date2)));
$total_month = 0;
while (($d1 = strtotime("+1 MONTH", $d1)) <= $d2) {
$total_month++;
}
echo $total_month;
I have used this and works in all conditions
$fiscal_year = mysql_fetch_row(mysql_query("SELECT begin,end,closed FROM fiscal_year WHERE id = '2'"));
$date1 = $fiscal_year['begin'];
$date2 = $fiscal_year['end'];
$ts1 = strtotime($date1);
$ts2 = strtotime($date2);
$te=date('m',$ts2-$ts1);
echo $te;