Date Period PHP - php

I want to render dates period base on start date and end date, for example:
Input:
Start date: 30/12/2017
End date: 31/03/2017
Interval: every month
Output I want:
30/12/2017
30/01/2018
30/03/2018 (February is missing because it not have 30th)
There my code:
function period_days($start_date, $int, $end_date){
$begin = new DateTime( $start_date );
$end = new DateTime( $end_date );
$interval = DateInterval::createFromDateString($int);
$period = new DatePeriod($begin, $interval, $end->modify( '+1 day' ));
return $period;
}
echo period_days('30-12-2017', '1 month', '31-03-2018');
Result return wrong (3rd should be "2018-03-30"):
"2017-12-30 00:00:00"
"2018-01-30 00:00:00"
"2018-03-02 00:00:00"
Edit: Explain about Input:
Start date format can be '31/12/2017' or 'first Monday of January 2018' or 'third Tuesday of December 2017' or '28 December 2017' ...
Interval can be '1 day', '1 month', '2 months', '1 year' ...
End date format is d-m-Y '01/12/2018'
I use this function to add schedule recurring event, something like plugin The Event Calendar, you guys can see example on https://wpshindig.com/events/community/add

I could suggest you a work around.
Since DatePeriod breaks for February, we could get Year and month and append date separately. But this will only be working for one year.
Example :
function periodDays($start_date, $int, $end_date){
$begin = new DateTime($start_date);
$end = new DateTime($end_date);
$startDay = $begin->format("d");
$interval = DateInterval::createFromDateString($int);
$period = new DatePeriod($begin, $interval, $end);
foreach($period as $date){
echo $date->format("Y-m-") .$startDay. "<br>";
}
}

Related

Carbon custom start and end of the week by timestamp

I have a list of records with $clocked_in timestamps. I want to display its week start and end date, so I came up with this:
$timesheetWeekStartDate = Carbon::parse($clocked_in)->startOfWeek()->setTimezone($timezone)->addHours(12)->addMinute()->format('Y-m-d H:i');
$timesheetWeekEndDate = Carbon::parse($clocked_in)->endOfWeek()->setTimezone($timezone)->addHours(12)->addMinute()->format('Y-m-d H:i');
$timesheet->period = $timesheetsWeekStartDate . ' - ' . $timesheetWeekEndDate;
It seems to be working, but I would like to have customized start and end of week - add 12 hours ahead. So next week would start/end on 2022-05-23 12:01 - 2022-05-29 12:00, not 2022-05-23 23:59 - 2022-05-29 00:00.
For example, if $clocked_in is starts on Monday 05:00 I want it to display the previous week, not current(because its not 12:01 yet).
How I can achieve that by utilising Carbon?
Didn't find a solution in Carbon, so made it in plain DateTime, here is solution:
$timesheet->clocked_in = '2022-05-21 21:20:04';
$start = date('Y-m-d', strtotime('-2 week', strtotime($timesheet->clocked_in)));
$end = date('Y-m-d', strtotime('+2 week', strtotime($timesheet->clocked_in)));
$period = new DatePeriod(
new DateTime($start),
new DateInterval('P1W'),
new DateTime($end)
);
$periods = [];
foreach ($period as $periodDate) {
$start = $periodDate;
$end = clone $periodDate;
$periods[] = [
'start' => $start->setTimezone(new DateTimeZone($user->account->timezone))->add(new DateInterval('PT12H'))->add(new DateInterval('PT1M'))->format('Y-m-d H:i'),
'end' => $end->setTimezone(new DateTimeZone($user->account->timezone))->add(new DateInterval('P7D'))->add(new DateInterval('PT12H'))->format('Y-m-d H:i'),
];
}
foreach ($periods as $period) {
if (($timesheet->clocked_in >= $period['start']) && ($timesheet->clocked_in <= $period['end'])) {
$timesheets[$timesheetKey]->period = date('m/d/Y', strtotime($period['start'])) . ' - ' . date('m/d/Y', strtotime($period['end']));
}
}

Return Monday to Sundays of Current Week

I was wondering how to grab from Monday (03-12-2018) to Sundays (03-18-2018) dates. I know that if I use 'this sunday' it will return Sundays dates but how would I do that for all the rest? Using this on every week day would result in Monday and Tuesday (From this standing point) to be 19 and 20.
date_default_timezone_set('America/New_York');
$the_date = date('Y-m-d', strotime("this sunday"));
Try this:
date_default_timezone_set('America/New_York');
$monday = date('Y-m-d', strtotime("monday this week"));
$sunday = date('Y-m-d', strtotime("sunday this week"));
$period = new DatePeriod(
new DateTime($monday),
new DateInterval('P1D'),
(new DateTime($sunday))->modify('+1 day')
);
foreach ($period as $date) {
echo $date->format('Y-m-d'), "\n";
}
Demo https://implode.io/9qLW1K

php get today tomorrow and next day but ignore weekends

How can I get the current day, tomorrow and next day in PHP but ignore weekends?
I have already tried this code, but it will include Saturday and Sunday.
array(
'todayDate' => date('d/m/Y')
'tomorrowDate' => date('d/m/Y', strtotime(' +1 day')),
'nextDay' => date('l', strtotime(' +2 day'))
)
Thanks.
Use Weekday(s) with strtotime
date('l', strtotime(' +2 Weekdays'));
Fiddle
This finds the next weekday from a specific date (not including Saturday or Sunday):
echo date('Y-m-d', strtotime('2011-04-05 +2 Weekday'));
You could also do it with a date variable of course:
$myDate = '2011-04-05';
echo date('Y-m-d', strtotime($myDate . ' +2 Weekday'));
Try this, Get date between two date without weekdays(Saturday and Sunday).
$startdate = '10-06-2015';
$endDate = '17-06-2015' ;
$Workingdays = getdateBettwoDate($startdate,$endDate);
print_r($Workingdays);
function getdateBettwoDate($startdate,$enddate)
{
$start = new DateTime($startdate);
$end = new DateTime($enddate);
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($start, $interval, $end);
$x=0;
$a=array();
foreach ($period as $dt)
{
$temp=$dt->format("l d-m-Y");
$ArTemp=explode(' ',$temp);
if($ArTemp[0]=='Saturday' || $ArTemp[0]=='Sunday'){
}else{
$a[$x]=$ArTemp[1];
$x++ ;
}
}
$a[$x]=date('l', strtotime( $enddate))." ".$enddate;
return $a ;
}

PHP get dates between two dates not working as expected

I am trying to get all dates between two dates using DatePeriod class. Its working fine when the dates inputed are of the same month, but not returning all dates when the two dates are of different months.
If the dates are say 2013-06-27 and 2013-07-05 its only returning 2013-06-27, 2013-06-28, 2013-06-29, 2013-06-30. Its not giving the rest of the dates.
CODE
$begin = new DateTime($start);
$last = new DateTime($end);
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $last);
I cannot reproduce the behavior
<?php
$start = '2013-06-27';
$end = '2013-07-05';
$begin = new DateTime($start);
$last = new DateTime($end);
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $last, DatePeriod::EXCLUDE_START_DATE);
echo 'phpversion: ', phpversion(), "\n";
foreach ( $period as $dt ) {
echo $dt->format("l Y-m-d H:i:s"), "\n";
}
echo "done.\n";
prints
phpversion: 5.4.7
Friday 2013-06-28 00:00:00
Saturday 2013-06-29 00:00:00
Sunday 2013-06-30 00:00:00
Monday 2013-07-01 00:00:00
Tuesday 2013-07-02 00:00:00
Wednesday 2013-07-03 00:00:00
Thursday 2013-07-04 00:00:00
done.
Which version of php do you use?

How to iterate, by month, between two specified dates

I have a website that was launched a few months ago. I would like to write some code that will look through every month, since launch, and grab metrics for that month.
My question is: What is the best way to specify a start date, and then iterate by month, all the way up until the current month (or to another specified date).
Does anyone have any suggestions? I'm using PHP and a mySQL database.
You could use strtotime, to increment the date by +1 month:
$date1 = strtotime('2009-01-01');
$date2 = strtotime('2010-01-01');
while ($date1 <= $date2) {
echo date('Y-m-d', $date1) . "\n";
$date1 = strtotime('+1 month', $date1);
}
And if you have PHP >= 5.3.0, you can use DateTime::add with an DateInterval object
Check the above example here.
I have a method which is optimal in results :
$begin = new DateTime( '2014-07-14' );
$end = new DateTime( '2014-08-01' );
$end = $end->modify( '+1 month' );
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($begin, $interval, $end);
foreach($period as $dt) {
var_dump($dt->format( "m" ));
}
Hope this will help.
If you start from last day of a 30 days month, you may lose some month in between using "+1 month". Try from 2015-06-30 to 2015-12-31 for example, it will skip september 2015.
Instead of using "+1 month", I suggest to use "first day of next month" instead:
$begin = new DateTime( '2015-06-30' );
$end = new DateTime( '2015-12-31' );
$end = $end->modify( 'first day of next month' );
$interval = DateInterval::createFromDateString('first day of next month');
$period = new DatePeriod($begin, $interval, $end);
foreach($period as $dt) {
var_dump($dt->format( "m" ));
}
this will list september 2015 as well.
I don't know the schema of your stored metrics, so here's a generic example:
Select total pageviews per month from Aug 1 thru Nov 30 2009
The code for MySQL:
SELECT DATE_FORMAT(s.date, '%Y-%m') AS year_month , SUM( s.pageviews ) AS s.pageviews_total
FROM statistics s
WHERE s.date BETWEEN '2009-08-01' AND '2009-11-30'
GROUP BY DATE_FORMAT(s.date, '%Y-%m')
ORDER BY DATE_FORMAT(s.date, '%Y-%m')
Having that aggregated table output may be enough for you. If not, you can loop through it with PHP and perform other manipulations.
$start_date = mktime(0, 0, 0, 1, 1, 2009);
$end_date = mktime(0, 0, 0, 10, 1, 2009);
$current_date = $start_date;
while($current_date <= $end_date) {
$current_date = strtotime("+1 month", $current_date);
}
That is one way to do it. Another one includes two loops over months and years separately.
But if you are know SQL well, you can get all your metrics and GROUP BY EXTRACT(YEAR_MONTH FROM date) right there in DB, which will most likely be faster.

Categories