Carbon - Laravel - Separate by Days - php

Look guys , i have two functions.
public function date(){
BusinessTime::enable(Carbon::class);
BusinessTime::enable(Carbon::class, [
'sunday' => ['08:00-22:00'],
'monday' => ['08:00-22:00'],
'tuesday' => ['08:00-22:00'],
'wednesday' => ['08:00-22:00'],
'thursday' => ['08:00-22:00'],
'friday' => ['08:00-23:59'],
'saturday' => ['00:00-23:59'],
'holidaysAreClosed' => true,
]);
$options = 0;
$date1 = Carbon::parse('2020-11-20 20:00')->diffInBusinessHours('2020-11-22 16:00:00', $options);
$date2 = $this->date2();
$date3 = $date2 - $date1;
echo 'Hours In'.round($date1);
echo '<br>';
echo 'Horas Out'.round($date3);
}
that return me all the hours , that are inside my range of bussiness hours .
and i have another function that return me all time between two dates .
public function date2(){
$start = Carbon::create(2020,11,20,20,0,0,'America/Recife');
$end = Carbon::create(2020,11,22,16,0,0,'America/Recife');
$options = 0;
return $start->diffInHours($end);
}
but how could i return on fuction date() , for example returne the diffInBusinessHours separate by day , where could be a array of date and hours . its possible ?

Are you using kylekatarnls/business-time?
If so, have you tried using $carbonDate->getOpeningHours() or Carbon::getOpeningHours()?

Related

Differentiate output message depending on time in array

I am trying to write a script which will display either an open or closed message depending on a businesses operating hours. I tried using the solution found here and adding to this by setting the timezone. However when I try to run this the value of $status is always 'closed' even if the time of day falls within the values in the array.
Here is my code, any advice would be appreciated. Thanks
//setting default timezone
date_default_timezone_set('Europe/Dublin');
//creating array of opening hours
$openingHours = [
'Sun' => ['12:00' => '20:30'],
'Wed' => ['16:00' => '21:00'],
'Thu' => ['16:00' => '21:00'],
'Fri' => ['16:00' => '23:00'],
'Sat' => ['16:00' => '21:00']
];
//current timestamp
$timestamp = time();
//default status
$status = 'closed';
//get time object from timestamp
$currentTime = (new DateTime())->setTimestamp($timestamp);
//loop through time range for current day
foreach ($openingHours[date('D', $timestamp)] as $startTime => $endTime) {
//create time objects from start and end times
$startTime = DateTime::createFromFormat('h:i A', $startTime);
$endTime = DateTime::createFromFormat('h:i A', $endTime);
//check if current time is within range
if (($startTime < $currentTime) && ($currentTime < $endTime)) {
$status = 'open';
break;
}//end off if
}//end off foreach
echo "we are currently :$status";
In your code the currentTime variable is an object so when you try comparing it things aren't going to match. Try this instead which simplifies things a little.
date_default_timezone_set('Europe/Dublin');
//creating array of opening hours
$openingHours = [
'Sun' => ['12:00' => '20:30'],
'Wed' => ['16:00' => '21:00'],
'Thu' => ['16:00' => '21:00'],
'Fri' => ['16:00' => '23:00'],
'Sat' => ['16:00' => '21:00']
];
//default status
$status = 'closed';
$timeNow = date('H:m',time());
//loop through time range for current day
foreach ($openingHours[date('D', time())] as $startTime => $endTime) {
//check if current time is within range
if (($startTime < $timeNow) && ($timeNow < $endTime)) {
$status = 'open';
break;
} //end off if
} //end off foreach
echo "we are currently :$status";
Edit on July 7th:
If you can change you the opening hours array slightly you may avoid multiple calls to date and the foreach loop using the code below.
date_default_timezone_set('Europe/Dublin');
//creating array of opening hours
$openingHours = [
'Sun' => ['Open'=>'12:00','Close' => '20:30'],
'Wed' => ['Open'=>'16:00','Close' => '21:00'],
'Thu' => ['Open'=>'16:00','Close' => '21:00'],
'Fri' => ['Open'=>'16:00','Close' => '23:00'],
'Sat' => ['Open'=>'16:00','Close' => '21:00']
];
$timeNow = date('H:m',time());
$dow = date('D',time());
echo 'We are currently :' . ((($openingHours[$dow]['Open'] < $timeNow) AND
($timeNow < $openingHours[$dow]['Close'])) ? 'open' : 'closed');

Adding a time to randomly generated list of dates

Down below I am trying to generate an array of dates that meet criteria of Sundays, Mondays, and Thursdays since the year 1990. With those dates, I want to add a time of 7 pm for every Event that is created. Is this possible with the Carbon package?
public function run()
{
$start = Carbon::parse('First Monday of January 1990');
$nextMonth = Carbon::now()->addMonth();
collect([
'monday' => false,
'thursday' => false,
'sunday' => true
])->flatMap(function ($bool, $day) use ($start, $nextMonth) {
return $this->dates($start, $nextMonth, $day, $bool);
})->sort(function ($a, $b) {
return strtotime($a) - strtotime($b);
})->values()->map(function ($date, $key) {
return factory(Event::class)->create([
'name' => 'Event '.($key + 1),
'slug' => 'event'.($key + 1),
'venue_id' => Venue::inRandomOrder()->first()->id,
'date' => $date
]);
})->filter(function ($event) {
return $event->date->lte(Carbon::today()->addWeeks(2));
});
}
protected function dates(Carbon $from, Carbon $to, $day, $last = false)
{
$step = $from->copy()->startOfMonth();
$modification = sprintf($last ? 'last %s of next month' : 'next %s', $day);
$dates = [];
while ($step->modify($modification)->lte($to)) {
$dates[$step->timestamp] = $step->copy();
}
return $dates;
}
To add a time of 7 pm you can use Carbon setter method $date->hour = 19. See http://carbon.nesbot.com/docs/#api-setters

Getting start date and end date of a week within month start and month end

I have a program to get the start date and end date of a week when passing year and week number. Following is the code.
function getStartAndEndDate($week, $year) {
$dto = new DateTime();
$dto->setISODate($year, $week,0);
$ret['week_start'] = $dto->format('Y-m-d');
$dto->modify('+6 days');
$ret['week_end'] = $dto->format('Y-m-d');
return $ret;
}
$week_array = getStartAndEndDate(5,2017);
print_r($week_array);
This will output result as
Array ( [week_start] => 2017-01-29 [week_end] => 2017-02-04 )
But I need to get week in two part. For eg the result should be as follows
Array ( [week_start] => 2017-01-29 [week_end] => 2017-01-31)
Array ( [week_start] => 2017-02-01 [week_end] => 2017-02-04)
which means I need separate values for different months. Any help will be appreciated.
You compare two date by month and use 't' format to get the last day of the month later. Follow the description of date() function to learn more about all available formats and the example below.
Also it's better to use DateTimeImmutable instead of DateTime unless you really need the mutable version.
function getStartAndEndDate($week, $year)
{
$dto = (new DateTimeImmutable())->setISODate($year, $week, 0);
$weekStart = $dto;
$weekEnd = $dto->modify('+6 days');
$ret = [];
if ($weekStart->format('m') === $weekEnd->format('m')) {
$ret[] = [
'week_start' => $weekStart,
'week_end' => $weekEnd,
];
} else {
$ret[] = [
'week_start' => $weekStart->format('Y-m-d'),
// 't' = the last day of the month.
'week_end' => $weekStart->format('Y-m-t'),
];
$ret[] = [
// The first day of the month.
'week_start' => $weekEnd->format('Y-m-01'),
'week_end' => $weekEnd->format('Y-m-d'),
];
}
return $ret;
}

How to get all months between two dates in PHP?

I have 2 dates. I want to get all months with total days in each.
How can I do this in PHP?
For example
$date1 = '2013-11-13'; // yy-mm-dd format
$date2 = '2014-02-14';
Output
Months Total Days
-----------------------
11-2013 30
12-2013 31
01-2014 31
02-2014 28
Just try with:
$date1 = '2013-11-15';
$date2 = '2014-02-15';
$output = [];
$time = strtotime($date1);
$last = date('m-Y', strtotime($date2));
do {
$month = date('m-Y', $time);
$total = date('t', $time);
$output[] = [
'month' => $month,
'total' => $total,
];
$time = strtotime('+1 month', $time);
} while ($month != $last);
var_dump($output);
Output:
array (size=4)
0 =>
array (size=2)
'month' => string '11-2013' (length=7)
'total' => string '30' (length=2)
1 =>
array (size=2)
'month' => string '12-2013' (length=7)
'total' => string '31' (length=2)
2 =>
array (size=2)
'month' => string '01-2014' (length=7)
'total' => string '31' (length=2)
3 =>
array (size=2)
'month' => string '02-2014' (length=7)
'total' => string '28' (length=2)
Try the below given code :
$date1 = '2013-11-15'; // yy-mm-dd format
$date2 = '2014-02-15';
$start = new DateTime($date1);
$start->modify('first day of this month');
$end = new DateTime($date2);
$end->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y-m") ." " ;
echo cal_days_in_month(CAL_GREGORIAN,$dt->format("m"),$dt->format("Y")) . "<br/>";
}
Also, checkout this link for more
i used timestamp and date:
$date1 = '2013-11-15'; // yy-mm-dd format
$date2 = '2014-02-15';
$d1 = strtotime('2013-11-15');
$d2 = strtotime('2014-02-15');
while ($d1 <= $d2) {
echo date('m-d-Y', $d1)." | ";
echo cal_days_in_month(CAL_GREGORIAN, date('m', $d1), date('Y', $d1)) ."<br>";
$d1 = strtotime("+1 month", $d1);
}
This should help you, Check out,
$date1 = new DateTime('2013-11-15');
$date1->modify('first day of this month');
$date2 = new DateTime('2014-02-15');
$date2->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$value = new DatePeriod($date1, $interval, $date2);
foreach ($value as $dates) {
echo $dates->format("m- Y")."-->".cal_days_in_month(0,$dates->format("m"),$dates->format("Y"))."<br>\n";
}
This is what i came up with:
$arr_months = array();
$date1 = new DateTime('2013-11-15');
$date2 = new DateTime('2014-02-15');
$month1 = new DateTime($date1->format('Y-m')); //The first day of the month of date 1
while ($month1 < $date2) { //Check if the first day of the next month is still before date 2
$arr_months[$month1->format('Y-m')] = cal_days_in_month(CAL_GREGORIAN, $month1->format('m'), $month1->format('Y')); //Add it to the array
$month1->modify('+1 month'); //Add one month and repeat
}
print_r($arr_months);
It creates an associative array with the month as key and the number of days as value.
The array created from the example would be:
Array
(
[2013-11] => 30
[2013-12] => 31
[2014-01] => 31
[2014-02] => 28
)
With a foreach loop you will be able to scroll trough the array easily.
You can use the DateTime class along with cal_day_in_month() like this
$datetime1 = "2014-02-15";
$datetime2= "2013-03-15";
$date1 = new DateTime($datetime1);
$date2 = new DateTime($datetime2);
while (date_format($date2, 'Y-m') <= date_format($date1, 'Y-m'))
{
$date2 = $date2->add(new DateInterval('P1M'));
echo $date2->format('Y-m')." | ".cal_days_in_month(CAL_GREGORIAN, $date2->format('m'), $date2->format('Y'))."<br>";
}

Logo change with date script

I just wondered if anybody can point me in the right direction: I'm looking to make a script whereby the logo on my site changes depending on the date; so for instance a haloween style one soon.
I started off by having 2 arrays, 1 of start dates and 1 of end dates(not sure even if this is the best way!):
<?php
$start_dates = array('01/01' => 'New Years',
'14/02' => 'Valentine Day',
'16/02/2010' => 'Pancake Day',
'17/03' => 'St Patricks Day',
'01/04' => 'April Fools',
'02/04/2010' => 'Easter',
'23/04' => 'St Georges Day',
'11/06/2010' => 'World Cup',
'31/10' => 'Halloween',
'05/11' => 'Guy Fawkes',
'11/11' => 'Armistice Day',
'16/10' => 'Today',
'15/12' => 'Christmas');
$end_dates = array( '08/01' => 'New Years',
'15/02' => 'Valentine Day',
'17/02/2010' => 'Pancake Day',
'18/03' => 'St Patricks Day',
'02/04' => 'April Fools',
'06/04/2010' => 'Easter',
'24/04' => 'St Georges Day',
'12/07/2010' => 'World Cup',
'01/11' => 'Halloween',
'06/11' => 'Guy Fawkes',
'12/11' => 'Armistice Day',
'17/10' => 'Today',
'01/01' => 'Christmas');
?>
Easy so far...the problemis that I need a way of working out if todays date falls between the start date and end date, then changing the image file name.
Its a long shot but I hope someone would be kind enough to help.
Thanks,
B.
like this
$events = array(
'New Year' => '01/01 01/08',
'Pancake Day' => '16/02/2010 17/02/2010',
//etc
);
echo find_event($events, '16/02');
where find_event() is
function mdy2time($date) {
$e = explode('/', $date);
if(count($e) < 3)
$e[] = '2010';
return strtotime("$e[1]-$e[0]-$e[2]");
}
function find_event($events, $date = null) {
$date = is_null($date) ? time() : mdy2time($date);
foreach($events as $name => $range) {
list($start, $end) = explode(' ', $range);
if($date >= mdy2time($start) && $date <= mdy2time($end))
return $name;
}
return null;
}
you should use an array more like this:
$dates = array();
$dates[] = array(
'name' => 'New Years'
'start' = '01/14',
'end' => '01/20',
'style' => 'haloween',
);
$dates[] = array(
//...
);
then you can get the style as follows:
$style='default';
// date as number e.g. 130 (january 30th)
$currDate = date('md',time()) * 1;
foreach ($dates AS $k => $v) {
$tmp = explode("/",$v['start'];
$start = ($tmp[1].$tmp[0])*1;
$tmp = explode("/",$v['end'];
$stop = ($tmp[1].$tmp[0])*1;
if ($start <= $currDate && $currDate < $stop) {
$style=$v['style'];
break;
}
}
echo 'style: '.$style;
Didn't check the code yet, so feel free to correct me if iam wrong.

Categories