Carbon custom start and end of the week by timestamp - php

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']));
}
}

Related

How to count date from a day only without have any specific date in a week

I want to detect how to detect if the day is in the specific settings that I save.
I already save the settings
$checkday = "Sunday";
$period = "48"; // this in hours
So I need to check if today in this week is Sunday + 48 hours after (means Tuesday) then run a function.
I already make these code
$starttimer = date('Y-m-d 00:00:00', strtotime($checkday));
$endtimer = date('Y-m-d H:i:s', strtotime('+' . $period . ' hour', strtotime(date('Y-m-d 00:00:00'))));
if(time() >= strtotime($starttimer) && time() <= strtotime($endtimer)){
// this should run a function
}
This code is working if today is Sunday, but the problem is when today is Monday it will detect next Week Monday. I need it to check from this week Sunday + 48 hours after then run function.
The conclusion is I want to run the function on every week start from Sunday + 48 hours after.
Thanks for reading my problem, hope someone can help me.
I think you need get day of this week.
because if checkday = "Monday" then $starttimer will return Monday of next week.
<?php
$checkday = 'Monday';
$period = 48;
$day_this_week = "$checkday this week";
$starttimer = date('Y-m-d 00:00:00', strtotime($day_this_week));
$endtimer = date('Y-m-d H:i:s', strtotime('+' . $period . ' hour', strtotime(date('Y-m-d 00:00:00'))));
var_dump($starttimer);//string(19) "2022-09-12 00:00:00"
You can use the flexibility of strtotime to find the time of the last occurance of $checkDay. You also need to check to see that today is the check day and run in that condition as well.
<?php
$checkDay = 'Sunday';
$period = 48;
$isCheckDay = date('w', strtotime($checkDay)) === date('w');
$start = strtotime('last ' . $checkDay);
$end = strtotime(date('Y-m-d', $start) . ' +' . $period . ' hours');
$now = time();
if ($isCheckDay || ($now >= $start && $now <= $end)) {
echo 'run function';
}
It is not necessary to work with timestamps. Datetime objects can be directly compared. This makes the code easier to read.
$checkday = "Sunday";
$period = "2 Days";
$dtStart = date_create('Tomorrow')->modify('last '.$checkday);
$dtEnd = (clone $dtStart)->modify($period);
/* Use 'Now' instead of 'Today' in the following line
* if the time periods can also be fractions of days.
*/
$dtToDay = date_create('today');
if($dtToDay >= $dtStart AND $dtToDay < $dtEnd){
echo 'run function';
}
else {
echo 'do nothing';
}
$dtStart is always the last $checkday weekday before tomorrow. A time in hours can also be entered for $period, for example "48 hours".
Demo: https://3v4l.org/5d2Xt
You can use below code for fulfill your requirement...
<?php
$checkday = "Sunday";
$period = "48"; // this in hours
echo date('l', strtotime($checkday. ' + '.$period.' hours'));
?>

Date Period 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>";
}
}

php how to store monday to friday of the next 6 months begin from tomorrow in an array

I am making a page to let the clients choose a date for an appointment, so I need to build a list of the dates like this :
always begin from tomorrow, end by 6 months
always from Mondy to Saturday, no Sunday
the day of the week need to be in chinese, like "Monday" is "星期一", but the timezone is in France
Here is the php
date_default_timezone_set('Europe/Paris');
$tomorrow = date("Y年m月d日 l", time() + 86400);
$end = date("Y年m月d日 l", time() + 86400 * 7); // just 7 days for a try
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($tomorrow, $interval, $end);
foreach ($daterange as $date) {
echo $date . '<br/>';
}
This code is not working.
I need to build an array, which store all the dates of next 6 months, begin from tomorrow, without Sunday, the days need to be in chinese and the timezone needs to be in Europe, is that possible?
I think strtotime and array_push is what you are looking for. Try this:
$curDate = date('Y-m-d', strtotime('+1 day'));
$endDate = date('Y-m-d', strtotime('+6 months +1 day'));
$myArr = array();
while ($endDate >= $curDate) {
if (date('w', strtotime($curDate)) !== '0') array_push($myArr, $curDate);
$curDate = date('Y-m-d', strtotime($curDate . " +1 days"));
}
var_dump($myArr);
For the Options, create an array from sunday to saturday.
$weekdays = array('Sunday', ..., 'Saturday');
echo date('Y/m/d', strtotime($curDate)) . ' ' . $weekdays[date('w', strtotime($curDate))];

How to divide datetime period into separate days in PHP

I need to divide time period for example from:
2015-11-22 11:22:33 to 2015-11-24 02:02:04
into something like this:
2015-11-22 11:22:33 - 2015-11-22 23:59:59
2015-11-23 00:00:00 - 2015-11-23 23:59:59
2015-11-24 00:00:00 - 2015-11-24 02:02:04.
It has to work also for periods shorter than 24h, so for
2015-11-22 11:22:33 to 2015-11-23 02:02:04
I need this:
2015-11-22 11:22:33 - 2015-11-22 23:59:59
2015-11-23 00:00:00 - 2015-11-23 02:02:04.
I found almost perfect piece of code, but it only works for periods longer than 24h and I don't know how to tune it.
<?php
$start_date = '27:04:2013';
$start_time = '16:30';
$end_date = '29:04:2013';
$end_time = '22:30';
// Date input strings and generate a suitable DatePeriod
$start = DateTime::createFromFormat("d:m:Y H:i", "$start_date $start_time");
$end = DateTime::createFromFormat("d:m:Y H:i", "$end_date $end_time");
$interval = new DateInterval('P1D');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $date) {
// Get midnight at start of current day
$date_start = clone $date;
$date_start->modify('midnight');
// Get 23:59:59, end of current day
// (moving to midnight of next day might be good too)
$date_end = clone $date;
$date_end->modify('23:59:59');
// Take care of partial days
$date_start = max($start, $date_start);
$date_end = min($end, $date_end);
// Here you would construct your array of
// DateTime pairs, or DateIntervals, as you want.
printf(
"%s -> %s \n",
$date_start->format('Y-m-d H:i'),
$date_end->format('Y-m-d H:i')
);
}
?>
Try this:
$date1 = '2015-11-22 11:22:33';
$date2 = '2015-11-23 12:22:34';
$f1 = strtotime($date1);
$f2 = strtotime(substr($date1, 0, 10) . " 23:59:59");
while($f2 < strtotime($date2)) {
print(date('Y-m-d H:i:s',$f1) .' - ' .date('Y-m-d H:i:s',$f2).'<br>');
$f1 = strtotime(date('Y-m-d H:i:s', $f2) .' +1 second');
$f2 = strtotime(date('Y-m-d H:i:s', $f2) .' +1 day');
}
print(date('Y-m-d H:i:s',$f1) .' - ' .$date2.'<br>');
See here: http://sandbox.onlinephpfunctions.com/code/77eaae15fdd7c0d2ca1f02a2d225c17199218819
$datetime1 = new DateTime('2015-11-22 11:22:33');
$datetime2 = new DateTime('2015-11-23 02:02:04');
$interval = $datetime1->diff($datetime2);
var_dump($interval->format('%y-%m-%d %h:%i:%s'));
// RESULT: string(14) "0-0-0 14:39:31"
References:
http://php.net/manual/de/datetime.diff.php
http://php.net/manual/de/class.dateinterval.php
http://php.net/manual/de/dateinterval.format.php

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 ;
}

Categories