'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?



Solution 1:[1]

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1