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
Related
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()?
Hi I have the following php event
public function onRenderDate(Event $event, $propertyValue)
{
// $propertyValue will be something like 1970-01-01,need to split the value in to following format
pr($propertyValue);
pr(getType($propertyValue));
$arr = [
'year' => 2016,
'month' => 07,
'day' => 01
];
return $arr;
}
Now I hardcoded the $arr, how can I split my $propertyValue(which returns a string date (2016-10-05T00:00:00+00:00)) in to the $arr, so that I can get each individual values like that? Any idea guys? Thanks in advance
public function onRenderDate(Event $event, $propertyValue)
{
$time = strtotime( $propertyValue);
$newformat = date('Y-m-d',$time);
$newformatArr = explode('-',$newformat);
$arr = [
'year' => $newformatArr[0],
'month' => $newformatArr[1],
'day' => $newformatArr[2]
];
return $arr;
}
You can do this using strtotime() php function. The function expects to be given a string containing an English date format and will try to parse that format into a Unix timestamp. Using timestamp, you can get day, month and year using date() function. Below i have update your function.
public function onRenderDate(Event $event, $propertyValue)
{
$timestamp = strtotime( $propertyValue);
$arr = [
'year' => date('Y', $timestamp),
'month' => date('m', $timestamp),
'day' => date('d', $timestamp)
];
return $arr;
}
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;
}
Example:
$startDate is Monday 2007-02-05 and $endDate is Tuesday 2007-02-20. Then I want it to list:
Monday 2007-02-05
Monday 2007-02-12
Monday 2007-02-19
I looked at the PHP manual and found this to get all the days between two dates. But how to do it the way i want? PHP Code:
Rather than get all days and loop through them all, get the first Monday after the start date and then iterate 7 days at a time:
$endDate = strtotime($endDate);
for($i = strtotime('Monday', strtotime($startDate)); $i <= $endDate; $i = strtotime('+1 week', $i))
echo date('l Y-m-d', $i);
I needed the same and created a simple method.
public function getMondaysInRange($dateFromString, $dateToString)
{
$dateFrom = new \DateTime($dateFromString);
$dateTo = new \DateTime($dateToString);
$dates = [];
if ($dateFrom > $dateTo) {
return $dates;
}
if (1 != $dateFrom->format('N')) {
$dateFrom->modify('next monday');
}
while ($dateFrom <= $dateTo) {
$dates[] = $dateFrom->format('Y-m-d');
$dateFrom->modify('+1 week');
}
return $dates;
}
Then use it.
$dateFromString = '2007-02-05';
$dateToString = '2007-02-20';
var_dump($this->getMondaysInRange($dateFromString, $dateToString));
Result:
array (size=3)
0 => string '2007-02-05' (length=10)
1 => string '2007-02-12' (length=10)
2 => string '2007-02-19' (length=10)
Maybe it will be helpful for somebody.
You can use below function to get a array of dates between a date range of specific day.
You have to input start date, end date and day number in number.The day number is as follow.
1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday. 5 = Friday, 6 = Saturday, 7 = Sunday.
function getDateForSpecificDayBetweenDates($startDate,$endDate,$day_number){
$endDate = strtotime($endDate);
$days=array('1'=>'Monday','2' => 'Tuesday','3' => 'Wednesday','4'=>'Thursday','5' =>'Friday','6' => 'Saturday','7'=>'Sunday');
for($i = strtotime($days[$day_number], strtotime($startDate)); $i <= $endDate; $i = strtotime('+1 week', $i))
$date_array[]=date('Y-m-d',$i);
return $date_array;
}
for ($i = strtotime($startDate); $i <= strtotime($endDate); $i = strtotime('+1 day', $i)) {
if (date('N', $i) == 1) //Monday == 1
echo date('l Y-m-d', $i); //prints the date only if it's a Monday
}
i Create A class, You get All Days In range Date Group By Name of Day:
class DayHelper{
const MONDAY = 'Mon';
const TUESDAY = 'Tue';
const WEDENSDAY = 'Wed';
const THURSDAY = 'Thu';
const FRIDAY = 'Fri';
const SATURDAY = 'Sat';
const SUNDAY = 'Sun';
public function GetYeardays($dateStart, $dateend){
$period = new \DatePeriod(
new \DateTime($dateStart), new \DateInterval('P1D'), (new \DateTime($dateend))
);
$dates = iterator_to_array($period);
$arrayreturn = array();
foreach ($dates as $val) {
$date = $val->format('Y-m-d'); //format date
$get_name = date('l', strtotime($date)); //get week day
$day_name = substr($get_name, 0, 3); // Trim day name to 3 chars
switch ($day_name) {
case self::MONDAY:
$MONDAY[] = $date;
$arrayreturn[self::MONDAY] = $MONDAY;
break;
case self::TUESDAY:
$TUESDAY[] = $date;
$arrayreturn[self::TUESDAY] = $TUESDAY;
break;
case self::WEDENSDAY:
$WEDENSDAY[] = $date;
$arrayreturn[self::WEDENSDAY] = $WEDENSDAY;
break;
case self::THURSDAY:
$THURSDAY[] = $date;
$arrayreturn[self::THURSDAY] = $THURSDAY;
break;
case self::FRIDAY:
$FRIDAY[] = $date;
$arrayreturn[self::FRIDAY] = $FRIDAY;
break;
case self::SATURDAY:
$SATURDAY[] = $date;
$arrayreturn[self::SATURDAY] = $SATURDAY;
break;
case self::SUNDAY:
$SUNDAY[] = $date;
$arrayreturn[self::SUNDAY] = $SUNDAY;
break;
}
}
return $arrayreturn;
}
}
The Output will be like this
array (size=7)
'Fri' =>
array (size=5)
0 => string '2016/01/01' (length=10)
1 => string '2016/01/08' (length=10)
2 => string '2016/01/15' (length=10)
3 => string '2016/01/22' (length=10)
4 => string '2016/01/29' (length=10)
'Sat' =>
array (size=5)
0 => string '2016/01/02' (length=10)
1 => string '2016/01/09' (length=10)
2 => string '2016/01/16' (length=10)
3 => string '2016/01/23' (length=10)
4 => string '2016/01/30' (length=10)
'Sun' =>
array (size=4)
0 => string '2016/01/03' (length=10)
1 => string '2016/01/10' (length=10)
2 => string '2016/01/17' (length=10)
3 => string '2016/01/24' (length=10)
'Mon' =>
array (size=4)
0 => string '2016/01/04' (length=10)
1 => string '2016/01/11' (length=10)
2 => string '2016/01/18' (length=10)
3 => string '2016/01/25' (length=10)
'Tue' =>
array (size=4)
0 => string '2016/01/05' (length=10)
1 => string '2016/01/12' (length=10)
2 => string '2016/01/19' (length=10)
3 => string '2016/01/26' (length=10)
'Wed' =>
array (size=4)
0 => string '2016/01/06' (length=10)
1 => string '2016/01/13' (length=10)
2 => string '2016/01/20' (length=10)
3 => string '2016/01/27' (length=10)
'Thu' =>
array (size=4)
0 => string '2016/01/07' (length=10)
1 => string '2016/01/14' (length=10)
2 => string '2016/01/21' (length=10)
3 => string '2016/01/28' (length=10)
I made some changes to response https://stackoverflow.com/a/37300272/6871295
Then I can get the days between dates for any day and return format.
public function getWeekDayInRange($weekday, $dateFromString, $dateToString, $format = 'Y-m-d')
{
$dateFrom = new \DateTime($dateFromString);
$dateTo = new \DateTime($dateToString);
$dates = [];
if ($dateFrom > $dateTo) {
return $dates;
}
if (date('N', strtotime($weekday)) != $dateFrom->format('N')) {
$dateFrom->modify("next $weekday");
}
while ($dateFrom <= $dateTo) {
$dates[] = $dateFrom->format($format);
$dateFrom->modify('+1 week');
}
return $dates;
}
This is code for fetching the weekday of "$startdate" and counting the number of weekdays between two dates.
`$startdate` = '2015-03-01';
`$endate` = '2015-03-31';
`$recurringDay` = date('N', strtotime($startdate)); // recurring Day from date i.e monday = 1, Tuesday = 2 ...etc
$begin = new DateTime(`$startdate`);
$end = new DateTime(date('Y-m-d',strtotime('+1 day', strtotime($endate))));
while($begin format('Y-m-d');
$day[] = $begin->format('N');
$begin->modify('+1 day');
}
$c=0; // counter starts
foreach($day as $key=>$dt) {
if ($dt==`$recurringDay`) // compare it
{
$k[] = $key;
$c++;
}
}
`$nofDays` = $c; // number of mondays , tuesday
foreach($k as $pp) {
//adding session code
`$recurringDatetime[]` = $period[$pp]; // recurring dates
}
print_r(`$recurringDatetime`); // array of dates of monday, tuesday ..etc
$dates = array();
$dates[] = strtotime($start);
for($i = 0; $i <= 12; $i++){
$dates[] = strtotime('+1 week', $dates[$i]);
}
foreach($dates as $date){ echo date("d.m.Y", $date); }
I had similar issue and courses can start on any day. This script picks starting day and collect next days every week until the wanted amount (12 in this case).
Convert $startDate and $endDate before that to timestamps:
foreach ($date = $startDate; $date <= $endDate; $date += 60 * 60 * 24) {
if (strftime('%w', $date) == 1) {
$mondays[] = strftime('%A %Y-%m-%d', $date);
}
}
simply you can add as,
$date_from = "2007-02-05";
$date_from = strtotime($date_from);
$date_to="2007-02-20";
$date_to = strtotime($date_to);
for ($i=$date_from; $i<=$date_to; $i+=86400) {
$day = date("Y-m-d", $i);
$unixTimestamp = strtotime($day);
$dayOfWeek = date("l", $unixTimestamp);
if ($dayOfWeek == "Monday") {
echo $day ."is a". $dayOfWeek;
}
}//end for
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.