I have a two dates. start date and end date. Using those dates i have to find recur dates.
example:
(1) start date = 2014-01-01
end date = 2014-05-01
expected output:
2014-01-01
2014-02-01
2014-03-01
2014-04-01
2014-05-01
(2) start date = 2014-01-31
end date = 2014-05-01
expected output:
2014-01-31
2014-02-28
2014-03-31
2014-04-30
means do not skip month, if month is skip in that case use last day of month. how to achive this thing?
I am using following code but i added 1 month in date so it skip the month:
$start = strtotime($start_date);
$end = strtotime($end_date);
$total_dates = array();
for($i=$start; $i<=$end;)
{
$date = date('Y-m-d',$start);
if($i>$start)
{
$next_date = date('Y-m-d',strtotime($date . "+1 month"));
$start = strtotime($next_date);
}
else
{
$next_date = date('Y-m-d',$start);
}
$total_dates[] = $next_date;
$date1 = new DateTime($date);
$newdate = date('Y-m-d',strtotime($date . "+1 month"));
$date2 = new DateTime($newdate);
$diff = $date2->diff($date1)->format("%a");
/* Find diff between two dates */
$i = (($i*1)+(86400*$diff)); //seconds in 1month
}
print_r($total_dates);
so in short:
start date = 2014-01-01
end date = 2014-05-01
expected output:
2014-01-31
2014-02-28
2014-03-31
2014-04-30
current output:
2014-01-31
2015-03-03
2015-04-03
check this
$start_date = '2015-01-31';
$end_date = '2016-06-01';
$start_date=date('Y-m-1', strtotime($start_date));
$diff = abs(strtotime($end_date) - strtotime($start_date));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
if($years>0){$loop=$years*12+$months;}else{$loop=$months;}
for($i=1; $i<=$loop+1;$i++)
{
$total_dates[] =$a= date('Y-m-t', strtotime($start_date));
$start_date = date('Y-m-d',strtotime($start_date . "+1 month"));
}
print_r($total_dates);
//output Array ( [0] => 2015-01-31 [1] => 2015-02-28 [2] => 2015-03-31 [3] => 2015-04-30 [4] => 2015-05-31 [5] => 2015-06-30 [6] => 2015-07-31 [7] => 2015-08-31 [8] => 2015-09-30 [9] => 2015-10-31 [10] => 2015-11-30 [11] => 2015-12-31 [12] => 2016-01-31 [13] => 2016-02-29 [14] => 2016-03-31 [15] => 2016-04-30 [16] => 2016-05-31 [17] => 2016-06-30 )
Try this...
<?php
$start_date = "2014-01-01";
$end_date = "2014-05-01";
$d = date_parse_from_format("Y-m-d", $start_date);
$start= $d["month"];
$d1 = date_parse_from_format("Y-m-d", $end_date);
$end= $d1["month"];
$array=array();
$array[]=date('Y-m-t', strtotime($start_date));
for($i=$start;$i<$end;$i++)
{
$str=explode("-",$start_date);
$mon=$str[1]+$i;
$newdate=$str[0]."-".$mon."-".$str[2];
$array[]=date('Y-m-t', strtotime($newdate));
}
print_r($array);
output:
2014-01-31
2014-02-28
2014-03-31
2014-04-30
2014-05-31
Use PHP date/time functions with relative interval formats:
http://php.net/manual/en/datetime.formats.relative.php
You can provide intervals like "last day of next month" or "last sat of July 2008", adding/subtracting this interval from the referenced date.
Related
Hi i have the following date = 2015-06-01 00:00:00
so i have to add 3 month to this date , so write the following code
$sarting="2015-06-01 00:00:00";
$date[$i]=date('Y-m-d', strtotime($sarting . "+3 months") );
And i get the output = 2015-09-01;
But now i want to add 3 month again and again for 20 times and i have to store the output to array
so i write the following code
$store_date=array();
for($i=0;$i<20;$i++){
$store_date[$i]=date('Y-m-d', strtotime($sarting . "+3 months") );
}
But the thing it's returning 2015-09-01 20 times . i need like this 2015-09-01, 2015-12-01,2016-06-01 etc .
Please check
I would recommend using the DateTime-class so we can reuse the same instance on each iteration.
$sarting = "2015-06-01 00:00:00";
$store_date = [];
// Create a DateTime-object we can reuse
$date = new DateTime($sarting);
for ($i = 0; $i < 20; $i++) {
$date->modify('+3 months');
$store_date[] = $date->format('Y-m-d');
}
print_r($store_date);
Since we're resuing the same object, it will keep adding 3 months to it on each iteration. No need for any calculations or anything, making the code clean and readable.
Demo: https://3v4l.org/KZiH9
You can use PHP's dateTime class' modify() method to add +3 months in loop to it.
<?php
$dateStamp = "2015-06-01 00:00:00";
$date = new DateTime($dateStamp);
$datesArr = [];
for ($i=1; $i<21 ; $i++) {
$date->modify('+3 month');
$datesArr[] = $date->format('Y-m-d h:i:s');
}
echo '<pre>';
print_r($datesArr);
echo '</pre>';
Output:
Array
(
[0] => 2015-09-01 12:00:00
[1] => 2015-12-01 12:00:00
[2] => 2016-03-01 12:00:00
[3] => 2016-06-01 12:00:00
[4] => 2016-09-01 12:00:00
[5] => 2016-12-01 12:00:00
[6] => 2017-03-01 12:00:00
[7] => 2017-06-01 12:00:00
[8] => 2017-09-01 12:00:00
[9] => 2017-12-01 12:00:00
[10] => 2018-03-01 12:00:00
[11] => 2018-06-01 12:00:00
[12] => 2018-09-01 12:00:00
[13] => 2018-12-01 12:00:00
[14] => 2019-03-01 12:00:00
[15] => 2019-06-01 12:00:00
[16] => 2019-09-01 12:00:00
[17] => 2019-12-01 12:00:00
[18] => 2020-03-01 12:00:00
[19] => 2020-06-01 12:00:00
)
Working Code:
You are not changing the value of $sarting. Try this:
$sarting = "2015-06-01 00:00:00";
$store_date = array();
for ($i = 0; $i < 20; $i++) {
$sarting = $store_date[$i] = date('Y-m-d', strtotime($sarting . "+3 months"));
}
Try this check if it helps,
$sarting="2015-06-01 00:00:00";
$store_date=array();
for($i=0;$i<20;$i++){
$store_date[$i]=date('Y-m-d', strtotime($sarting . "+3 months") );
$sarting=$store_date[$i];
}
echo "<pre>";
print_r($store_date);
echo "</pre>";
Below code for Addition or Subtraction for Year/Month/day from date
Addition = date('Y-m-d', strtotime("+0 years +3 months +0 days", strtotime($lastdate)));
Subtraction = date('Y-m-d', strtotime("+0 years -3 months +0 days", strtotime($lastdate)));
$lastdate = "01-12-2015"; //actual date
$after_3_month = date('Y-m-d', strtotime("+0 years +3 months +0 days", strtotime($lastdate))); // adding 3 month on the actual date
echo $after_3_month; //3 month added with actual date
$start_date = '2015-09-21';
$end_Date = '2016-09-21';
function getStartAndEndDate($start_date, $end_Date ){
$date1 = new DateTime($start_date);
$date2 = new DateTime($end_Date);
$interval = $date1->diff($date2);
$weeks = floor(($interval->days) / 7);
$date_differences = array();
for($i = 1; $i <= $weeks; $i++){
$date1->add(new DateInterval('P4D'));
$s_time = strtotime($start_date);
$week_number = date('W', $s_time);
$date_differences[] = $start_date." - ".$date1->format('Y-m-d')."<br>";
$date1->add(new DateInterval('P3D'));
$start_date = $date1->format('Y-m-d');
}
return $date_differences;
}
Output of the function is:
[0] => 2015-09-1 ## 2015-09-05
[1] => 2015-09-08 ## 2015-09-12
[2] => 2015-09-15 ## 2015-09-19
[3] => 2015-09-22 ## 2015-09-26
[4] => 2015-09-29 ## 2015-10-03
[5] => 2015-10-06 ## 2015-10-10
[6] => 2015-10-13 ## 2015-10-17
[7] => 2015-10-20 ## 2015-10-24
[8] => 2015-10-27 ## 2015-10-31
[9] => 2015-11-03 ## 2015-11-07
In this function, when i give start and end date, it returns me all weeks start and end date but the problem it works perfectly when i gave him start date which is exactly Monday. When i gave it a date which is not on Monday but some other days it simply add four days and makes week like (Tuesday to Saturday).
What i exactly want is if someone enters date which is not Monday, it should start its week with Monday. e.g. if
$start_date = '2015-09-21';
$end_Date = '2016-09-21';
it returns output like this:
[0] => 2015-08-31 ## 2015-09-04
[1] => 2015-09-07 ## 2015-09-11
[2] => 2015-09-14 ## 2015-09-18
[3] => 2015-09-21 ## 2015-09-25
Identify on which day the date is and calculate monday using DateTime:
$s = new DateTime('2016-09-23');
$s->modify('-' . $s->format('N')+1 . 'days');
//2016-09-19
echo $s->format('Y-m-d');
$date = new DateTime('your date');
$date->modify('-' . $date->format('N')+1 . 'days');
and print the date in which ever format you want :)
so my problem is rather simple but the solution keeps evading me. i am trying to get a list of future dates at a set interval that respects week nr in month and day nr in week. for example i need to make a list of dates of the 2nd mondays at 3 months apart.
i have a form where user specifies 2 dates and the interval.
so what i have is something like:
$start_date = "2015-01-07";
$end_date = "2016-01-07";
$period = "+1 month";
then, using this function from this link stackoverflow i get what weeknr my start_date is: (ie: "first monday")
function literalDate($timestamp) {
$timestamp = is_numeric($timestamp) ? $timestamp : strtotime($timestamp);
$weekday = date('l', $timestamp);
$month = date('M', $timestamp);
$ord = 1;
while(date('M', ($timestamp = strtotime('-1 week', $timestamp))) == $month) {
$ord++;
}
$lit = array(null, 'first', 'second', 'third', 'fourth', 'fifth');
return $lit[$ord].' '.$weekday;
}
$day_number = literalDate($start_date);
$list=array();
then. i'm trying to do this
while(strtotime($start_date) <= strtotime($end_date))
{
$list[]=$start_date;
$start_date=date('Y-m-d', strtotime("$start_date $period"));
$month = date('F', strtotime($start_date));
$start_date = date('Y-m-d', strtotime($day_number.' of '.$month)); //this always returns 1970-01-01
}
print_r($list);
as asked in comment my expected output is something like
array(
[0] => 2015-01-07
[1] => 2015-02-04
[2] => 2015-03-04
[3] => 2015-04-01
[4] => 2015-05-06
[5] => 2015-06-03
[6] => 2015-07-01
[7] => 2015-08-05
[8] => 2015-09-02
[9] => 2015-10-07
[10] => 2015-11-04
[11] => 2015-12-02
)
From what I understand, DateInterval should get you what you need:
$start = new DateTime('2015-01-07');
$start->modify('first day of this month');
$end = new DateTime('2016-01-07');
$end->modify('first day of this month');
$interval = DateInterval::createFromDateString('first wednesday');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
$d = $dt->format("d");
if($d <= 7){
echo $dt->format("Y-m-d") . "\n";
}
}
will display:
2015-01-07
2015-02-04
2015-03-04
2015-04-01
2015-05-06
2015-06-03
2015-07-01
2015-08-05
2015-09-02
2015-10-07
2015-11-04
2015-12-02
2016-01-06
strtotime() which works in reference of today.
strtotime("+x days");
strtotime
if you need something in relation to another date...
date("Y-m-d", strtotime($yourdate) + 86400 * $days);
I am tring to get the week from the month having starting Monday and end with Sunday with in same month.
i'll provide month and year.
for example:
$month = '03';
$year = '2014';
then function should return
2014-03-03 to 2014-03-09 as start date of month coz the month has its first Monday on 3rd.
then continue to month till last week.
In march, 2014, 31st starts on Monday but don't finish in march, it finishes at 06-04-2014 so this should not be included in counting.
Now, when i pass month as '04' than the month should count 31st march in its first week.
I hope i make my self clear, sorry for language.
I have tried so far:
$month = "04";
$year = "2014";
$beg = (int)date('W', strtotime("first day of $year-$month"));
$end = (int)date('W', strtotime("last day of $year-$month"));
$weeks = range($beg, $end);
foreach($weeks as $week) {
$result = $this->getStartAndEndDate($week, $year);
print_r($result);
}
function getStartAndEndDate($week, $year)
{
$time = strtotime("1 January $year", time());
$day = date('w', $time);
$time += ((7*$week)+1-$day)*24*3600;
$return[0] = date('Y-m-d', $time);
$time += 6*24*3600;
$return[1] = date('Y-m-d', $time);
return $return;
}
OUTPUT:
Array
(
[0] => 2014-03-03
[1] => 2014-03-09
)
Array
(
[0] => 2014-03-10
[1] => 2014-03-16
)
Array
(
[0] => 2014-03-17
[1] => 2014-03-23
)
Array
(
[0] => 2014-03-24
[1] => 2014-03-30
)
Array
(
[0] => 2014-03-31
[1] => 2014-04-06
)
Array
(
[0] => 2014-04-07
[1] => 2014-04-13
)
You can use the DateTime class for this:
$dt = new DateTime('1st march');
// is this a monday?
if($dt->format('N') !== '1') {
// if not, went to next monday
$dt->modify('next monday');
}
echo $dt->format('Y-m-d')
. ' to ' . $dt->modify('next sunday')->format('Y-m-d');
Output:
2014-03-03 to 2014-03-09
<?php
function get_weeks($month, $year) {
$weeks = array();
$date = DateTime::createFromFormat('mY', $month.$year);
$date->modify('first Monday of this month');
$end = clone $date;
$end->modify('last Monday of this month');
$interval = DateInterval::createFromDateString('1 week');
$period = new DatePeriod($date, $interval, $end);
$counter = 1;
foreach ($period as $dt) {
$end_of_week = clone $dt;
$end_of_week->modify('next Sunday');
$weeks[] = sprintf("Week %u: %s - %s",
$counter,
$dt->format('Y-m-d'),
$end_of_week->format('Y-m-d')
);
$counter++;
}
return $weeks;
}
$weeks = get_weeks('03', '2014');
print_r($weeks);
Array
(
[0] => Week 1: 2014-03-03 - 2014-03-09
[1] => Week 2: 2014-03-10 - 2014-03-16
[2] => Week 3: 2014-03-17 - 2014-03-23
[3] => Week 4: 2014-03-24 - 2014-03-30
)
See it in action
$start_date = "2013-05-01";
$last_date = "2013-08-30";
How can I get dates of tuesdays and thursdays between these two dates?
<?php
$start = new DateTime('2013-05-01');
$end = new DateTime('2013-08-30');
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
if ($dt->format("N") == 2 || $dt->format("N") == 4) {
echo $dt->format("l Y-m-d") . "<br>\n";
}
}
See it in action
What this code does:
Creates a starting date object using DateTime.
Creates a starting date object using DateTime.
Creates a DateInterval object to represent our interval of time to iterate through. In this case 1 day.
Creates a DatePeriod object to manage these objects.
Using DatePeriod, it iterates through the date starting with the starting date and ending at the end date. We use DateTime::format() with the N parameter to get the day number of the week. If the day number of the week is 2 (Tuesday) or 4 (Thursday) echo out it's value.
Some PHP-Fu
$start_date = '2013-05-01';
$last_date = '2013-08-30';
$dates = range(strtotime($start_date), strtotime($last_date),86400);
$days = array('tuesday' => array(), 'thursday' => array());
array_map(function($v)use(&$days){
if(date('D', $v) == 'Tue'){
$days['tuesday'][] = date('Y-m-d', $v);
}elseif(date('D', $v) == 'Thu'){
$days['thursday'][] = date('Y-m-d', $v);
}
}, $dates); // Requires PHP 5.3+
print_r($days);
Output
Array
(
[tuesday] => Array
(
[0] => 2013-05-07
[1] => 2013-05-14
[2] => 2013-05-21
[3] => 2013-05-28
[4] => 2013-06-04
[5] => 2013-06-11
[6] => 2013-06-18
[7] => 2013-06-25
[8] => 2013-07-02
[9] => 2013-07-09
[10] => 2013-07-16
[11] => 2013-07-23
[12] => 2013-07-30
[13] => 2013-08-06
[14] => 2013-08-13
[15] => 2013-08-20
[16] => 2013-08-27
)
[thursday] => Array
(
[0] => 2013-05-02
[1] => 2013-05-09
[2] => 2013-05-16
[3] => 2013-05-23
[4] => 2013-05-30
[5] => 2013-06-06
[6] => 2013-06-13
[7] => 2013-06-20
[8] => 2013-06-27
[9] => 2013-07-04
[10] => 2013-07-11
[11] => 2013-07-18
[12] => 2013-07-25
[13] => 2013-08-01
[14] => 2013-08-08
[15] => 2013-08-15
[16] => 2013-08-22
[17] => 2013-08-29
)
)
Online demo
$start_date = strtotime("2013-05-01");
$last_date = strtotime("2013-08-30");
while ($start_date <= $last_date) {
$start_date = strtotime('+1 day', $start_date);
if (date('N',$start_date) == 2 || date('N',$start_date) == 4){
echo date('Y-m-d', $start_date).PHP_EOL;
}
}
<?php echo date('Y-m-d', strtotime('next thursday', strtotime($start_date)));
Also for tuesday ofcourse
Please use the following function for your solution,
function daycount($day, $startdate, $lastdate, $counter=0)
{
if($startdate >= $lastdate)
{
return $counter;
}
else
{
return daycount($day, strtotime("next ".$day, $startdate), ++$counter);
}
}
$start_date = "2013-05-01";
$last_date = "2013-08-30";
echo "Tuesday Count - ".daycount("tuesday", strtotime($start_date), strtotime($last_date));
echo "<br/>";
echo "Thursday Count - ".daycount("thursday", strtotime($start_date), strtotime($last_date));
Try with this
$startDate = strtotime($start_date);
$endDate = strtotime($last_date);
while ($startDate < $endDate) {
echo date('Y-m-d', $startDate ). "\n";
// Give the condition to find last Tuesday
$startDate = strtotime( 'next Tuesday', $startDate );
}
With DateTime:
$start_date = "2013-05-01";
$last_date = "2013-08-30";
$start = new DateTime($start_date);
$clone = clone $start;
$start->modify('next thursday');
$thursday=$start->format('Y-m-d');
$clone->modify('next tuesday');
$tuesday=$clone->format('Y-m-d');
echo $thursday; //2013-05-02
echo $tuesday; //2013-05-07
We need to objects because if in interval tuesday is before thursday we will have next tuesday. But you can modify little code to use one object.
With the help of few php date functions this can be solved easily..
<?php
// Create the from and to date
$start_date = strtotime("2013-05-01");
$last_date = strtotime("2013-08-30");
// Get the time interval to get the tue and Thurs days
$no_of_days = ($last_date - $start_date) / 86400; //the diff will be in timestamp hence dividing by timestamp for one day = 86400
$get_tue_thu_days = array();
// Loop upto the $no_of_days
for($i = 0; $i < $no_of_days; $i++) {
$temp = date("D", $start_date);
if($temp == "Tue" || $temp == "Thu") {
$get_tue_thu_days[] = date("D/M/Y", $start_date); //formating date in Thu/May/2013 formate.
}
$start_date += 86400;
}
print_r($get_tue_thu_days);
if you have a reference date which you know is a tuesday/thursday you can find days which are a multiple of 7 days from your reference date, these days will always be the same day of the week.