Okay first of all, before some of you might put this question into a duplicate question. i have been go through many questions related to my question. But it seems like those questions cannot solve my problem. i want to find days between 2 dates excluding weekend and holidays. the questions that i have been go through declare the variable of $holiday in array and initialize the value in that array.
Below is my code in LeaveapplicationController.phpfor finding days exclude weekends
$date1 = $model->startDate;
$date2 = $model->endDate;
$date1 = strtotime($date1);
$date2 = strtotime($date2);
//Initialized public holiday
$holidays = array("2020-01-21", "2020-01-22", "2020-01-23");
$days = ($date2 - $date1)/86400 + 1;
$fullWeek = floor($days/7);
$remainDay = fmod($days,7);
$firstDay = date("N", $date1);
$lastDay = date("N", $date2);
if($firstDay <= $lastDay){
if($firstDay <= 6 && 6 <= $lastDay) $remainDay--;
if($firstDay <= 7 && 7 <= $lastDay) $remainDay--;
}
else
{
if($firstDay == 7){
$remainDay--;
if($lastDay == 6){
$remainDay--;
}
}
else{
$remainDay -= 2;
}
}
$workDay = $fullWeek * 5;
if($remainDay > 0)
{
$workDay += $remainDay;
}
foreach($holidays as $holiday){
$timeStamp = strtotime($holiday);
if($date1 <= $timeStamp && $timeStamp <= $date2 && date("N", $timeStamp) != 6 && date("N", $timeStamp) != 7)
$workDay--;
}
$model->no_of_days=$workDay;
$model->save();
So, i have tried with holiday that has been initialized with some values. In my case, i want to replace that $holiday=array() with data from another table of database. Is there any best way to do it?
Using DateTime
$start = new \DateTime($model->startDate); //2020-01-01
$end = new \DateTime($model->endDate); //2020-01-31
$endDate = $end->format('Y-m-d');
$interval = new \DateInterval('P1D');
$end->add($interval);
$period = new \DatePeriod($start, $interval, $end);
foreach ($period as $date) {
$allDates[] = [
'date' => $date->format('Y-m-d'),
'dayNo' => $date->format('N'),
];
}
//Initialized public holiday
$holidays = HolidayModelName::find()
->select('date')
->where(['between', 'date', $start->format('Y-m-d'), $endDate])
->indexBy('date')
->column();
$workDay = 0;
foreach ($allDates as $value) {
$isWeekOff = $value['dayNo'] == 6 || $value['dayNo'] == 7;
if (!$isWeekOff && !isset($holidays[$value['date']])) {
$workDay++;
}
}
// Result : 20 Work Days
Related
I try this
<?php
$startdate = '2016-07-15';
$enddate = '2016-07-17';
$sundays = [];
$startweek=date("W",strtotime($startdate));
$endweek=date("W",strtotime($enddate));
$year=date("Y",strtotime($startdate));
for($i=$startweek;$i<=$endweek;$i++) {
$result=$this->getWeek($i,$year);
if($result>$startdate && $result<$enddate) {
$sundays[] = $result;
}
}
print_r($sundays);
public function getWeek($week, $year)
{
$dto = new \DateTime();
$result = $dto->setISODate($year, $week, 0)->format('Y-m-d');
return $result;
}
?>
this return blank array. but in between two dates 2016-07-17 is Sunday.
I get output as 2016-07-17
I refer this here
But in this link return output as no of sunday not date.
Give this a try:
$startDate = new DateTime('2016-07-15');
$endDate = new DateTime('2016-07-17');
$sundays = array();
while ($startDate <= $endDate) {
if ($startDate->format('w') == 0) {
$sundays[] = $startDate->format('Y-m-d');
}
$startDate->modify('+1 day');
}
var_dump($sundays);
If you want later to use the DateTime objects instead of the formatted date, then you must use DateTimeImmutable for the $startDate variable:
$startDate = new DateTimeImmutable('2016-07-15');
$endDate = new DateTimeImmutable('2016-07-17');
$sundays = array();
while ($startDate <= $endDate) {
if ($startDate->format('w') == 0) {
$sundays[] = $startDate;
}
$startDate->modify('+1 day');
}
var_dump($sundays);
function getDateForSpecificDayBetweenDates($startDate, $endDate, $weekdayNumber)
{
$startDate = strtotime($startDate);
$endDate = strtotime($endDate);
$dateArr = array();
do
{
if(date("w", $startDate) != $weekdayNumber)
{
$startDate += (24 * 3600); // add 1 day
}
} while(date("w", $startDate) != $weekdayNumber);
while($startDate <= $endDate)
{
$dateArr[] = date('Y-m-d', $startDate);
$startDate += (7 * 24 * 3600); // add 7 days
}
return($dateArr);
}
$dateArr = getDateForSpecificDayBetweenDates('2010-01-01', '2010-12-31', 0);
print "<pre>";
print_r($dateArr);
Try out this code..
Try this
$start = new DateTime($startDate);
$end = new DateTime($endDate);
$sundays = [];
while ($start->getTimestamp() != $end->getTimestamp()) {
if ($start->format('w') == 0) {
$sundays[] = $start->format('Y-m-d');
}
$start->add('+1 DAY');
}
This will return you all sundays between two dates.
$startdate = '2016-05-1';
$enddate = '2016-05-20';
function getSundays($start, $end) {
$timestamp1 = strtotime($start);
$timestamp2 = strtotime($end);
$sundays = array();
$oneDay = 60*60*24;
for($i = $timestamp1; $i <= $timestamp2; $i += $oneDay) {
$day = date('N', $i);
// If sunday
if($day == 7) {
// Save sunday in format YYYY-MM-DD, if you need just timestamp
// save only $i
$sundays[] = date('Y-m-d', $i);
// Since we know it is sunday, we can simply skip
// next 6 days so we get right to next sunday
$i += 6 * $oneDay;
}
}
return $sundays;
}
var_dump(getSundays($startdate, $enddate));
Use Carbon
$arrayOfDate = [];
$startDate = Carbon::parse($startDate)->modify('this sunday');
$endDate = Carbon::parse($endDate);
for ($date = $startDate; $date->lte($endDate); $date->addWeek()) {
$arrayOfDate[] = $date->format('Y-m-d');
}
return $arrayOfDate;
Let's say that I have two dates:
$initialDate = '08/10/2015 09:30:24 am';
$finalDate = '15/10/2015 15:47:38 pm';
$holiday = '12/10/2015';
I have to consider the hour of these days.
Hours to consider : 8 hours per day;
Start : 8 pm
End: 18 pm (24 hours format )
Lunch break start: 12:00 pm
Lunch break end: 14:00 pm
Example 1 : From 08/10/2015 10:00:00 to 09/10/2015 17:00:00 results 13 working hours. ( excludes lunch break )
Example 2 : From 08/10/2015 14:00:00 to 09/10/2015 18:00:00 results 12 working hours. ( Do not exclude 2 hours from begin date, because starts after 14:00 pm, lunch break )
Example 3 : From 08/10/2015 16:00:00 to 09/10/2015 18:00:00 results 10 working hours. ( Do not exclude 2 hours from begin date, because starts after 14:00 pmm lunch break )
Exampld 4 : From 08/10/2015 08:00:00 to 09/10/2015 11:00:00 results 14 working hours. ( Exclude 2 hours from begin date, and do not exclude 2 hours from end date, because isn't after 14:00 pm )
And I have to calculate the working hours and working days between those two dates, excluding weekends and Holidays, how can I do that ? I'm using PHP.
PS: I Already have something, but without lunch break... I made a research here on StackOverFlow.
Code:
function get_workdays($dataInicial,$dataFinal){
// arrays
$days_array = array();
$skipdays = array("Saturday", "Sunday");
$skipdates = get_feriados();
// other variables
$i = 0;
$current = $dataInicial;
if($current == $dataFinal) // same dates
{
$timestamp = strtotime($dataInicial);
if (!in_array(date("l", $timestamp), $skipdays)&&!in_array(date("Y-m-d", $timestamp), $skipdates)) {
$days_array[] = date("Y-m-d",$timestamp);
}
}
elseif($current < $dataFinal) // different dates
{
while ($current < $dataFinal) {
$timestamp = strtotime($dataInicial." +".$i." day");
if (!in_array(date("l", $timestamp), $skipdays)&&!in_array(date("Y-m-d", $timestamp), $skipdates)) {
$days_array[] = date("Y-m-d",$timestamp);
}
$current = date("Y-m-d",$timestamp);
$i++;
}
}
return $days_array;
}
function get_feriados(){
$dateAno = Date('Y');
$days_array = array(
$dateAno.'-10-12', // Padroeira do Brasil/ Dias das Crianças
$dateAno.'-11-02', // Finados
$dateAno.'-12-25' // Finados
);
return $days_array;
}
date_default_timezone_set('America/Sao_Paulo');
$dateAno = Date('Y');
$dataInicial = Date('08/10/2015 H:i');
$dataFinal = Date('13/10/2015 H:i');
// timestamps
$from_timestamp = strtotime(str_replace('/', '-', $dataInicial));
$to_timestamp = strtotime(str_replace('/', '-', $dataFinal));
// work day seconds
$workday_start_hour = 9;
$workday_end_hour = 17;
$workday_seconds = ($workday_end_hour - $workday_start_hour)*3600;
// work days beetwen dates, minus 1 day
$from_date = date('Y-m-d',$from_timestamp);
$to_date = date('Y-m-d',$to_timestamp);
$workdays_number = count(get_workdays($from_date,$to_date))-1;
$workdays_number = $workdays_number<0 ? 0 : $workdays_number;
// start and end time
$start_time_in_seconds = date("H",$from_timestamp)*3600+date("i",$from_timestamp)*60;
$end_time_in_seconds = date("H",$to_timestamp)*3600+date("i",$to_timestamp)*60;
// final calculations
$working_hours = ($workdays_number * $workday_seconds + $end_time_in_seconds - $start_time_in_seconds) / 86400 * 24;
print_r('<br/> Horas Ășteis '.$working_hours);
}
But don't consider two hours of break lunch. Can somebody please help me ?
If you use PHP 5.3 or higher, you can do this:
$datefrom = DateTime::createFromFormat('d/m/Y', '08/10/2015');
$dateto = DateTime::createFromFormat('d/m/Y', '15/10/2015');
$interval = $datefrom->diff($dateto);
$days = intval($interval->format('%a'));
Also you can remove holidays with if:
if ($datetime1->getTimestamp() < $holiday->getTimestamp() and $datetime2->getTimestamp() > $holiday->getTimestamp()) $days--;
Calculate hours between two days:
$datefrom = DateTime::createFromFormat('d/m/Y H:i:s', '08/10/2015 12:51:34');
$dateto = DateTime::createFromFormat('d/m/Y H:i:s', '15/10/2015 13:14:56');
$hours = intval($interval->format('%a')) * 24 + $interval->format('%h');
You can calculate hours of launches sum and then subtract it.
How to ignore weekends or calculate ignore days:
while($dateto->getTimestamp() > $datefrom->getTimestamp()) {
if (in_array($datefrom->format('w'), array('0','6'))) $ignore_days += 1;
$datefrom->modify('+1 day');
}
I expect this will do all you want. But I changed the datetime format as follows. Check it. Used less comments. If any query, please ask. Holidays are arrays, add and remove as required.
Times between 12:00 - 14:00 is handled.
Times below 08:00 is handled.
Times above 18:00 is handled.
<?php
$initialDate = '2015-10-13 08:15:00'; //start date and time in YMD format
$finalDate = '2015-10-14 11:00:00'; //end date and time in YMD format
$holiday = array('2015-10-12'); //holidays as array
$noofholiday = sizeof($holiday); //no of total holidays
//create all required date time objects
$firstdate = DateTime::createFromFormat('Y-m-d H:i:s',$initialDate);
$lastdate = DateTime::createFromFormat('Y-m-d H:i:s',$finalDate);
if($lastdate > $firstdate)
{
$first = $firstdate->format('Y-m-d');
$first = DateTime::createFromFormat('Y-m-d H:i:s',$first." 00:00:00" );
$last = $lastdate->format('Y-m-d');
$last = DateTime::createFromFormat('Y-m-d H:i:s',$last." 23:59:59" );
$workhours = 0; //working hours
for ($i = $first;$i<=$last;$i->modify('+1 day') )
{
$holiday = false;
for($k=0;$k<$noofholiday;$k++) //excluding holidays
{
if($i == $holiday[$k])
{
$holiday = true;
break;
} }
$day = $i->format('l');
if($day === 'Saturday' || $day === 'Sunday') //excluding saturday, sunday
$holiday = true;
if(!$holiday)
{
$ii = $i ->format('Y-m-d');
$f = $firstdate->format('Y-m-d');
$l = $lastdate->format('Y-m-d');
if($l ==$f )
$workhours +=sameday($firstdate,$lastdate);
else if( $ii===$f)
$workhours +=firstday($firstdate);
else if ($l ===$ii)
$workhours +=lastday($lastdate);
else
$workhours +=8;
}
}
echo $workhours; //echo the hours
}
else
echo "lastdate less than first date";
function sameday($firstdate,$lastdate)
{
$fmin = $firstdate->format('i');
$fhour = $firstdate->format('H');
$lmin = $lastdate->format('i');
$lhour = $lastdate->format('H');
if($fhour >=12 && $fhour <14)
$fhour = 14;
if($fhour <8)
$fhour =8;
if($fhour >=18)
$fhour =18;
if($lhour<8)
$lhour=8;
if($lhour>=12 && $lhour<14)
$lhour = 14;
if($lhour>=18)
$lhour = 18;
if($lmin == 0)
$min = ((60-$fmin)/60)-1;
else
$min = ($lmin-$fmin)/60;
return $lhour-$fhour + $min;
}
function firstday($firstdate) //calculation of hours of first day
{
$stmin = $firstdate->format('i');
$sthour = $firstdate->format('H');
if($sthour<8) //time before morning 8
$lochour = 8;
else if($sthour>18)
$lochour = 0;
else if($sthour >=12 && $sthour<14)
$lochour = 4;
else
{
$lochour = 18-$sthour;
if($sthour<=14)
$lochour-=2;
if($stmin == 0)
$locmin =0;
else
$locmin = 1-( (60-$stmin)/60); //in hours
$lochour -= $locmin;
}
return $lochour;
}
function lastday($lastdate) //calculation of hours of last day
{
$stmin = $lastdate->format('i');
$sthour = $lastdate->format('H');
if($sthour>=18) //time after 18
$lochour = 8;
else if($sthour<8) //time before morning 8
$lochour = 0;
else if($sthour >=12 && $sthour<14)
$lochour = 4;
else
{
$lochour = $sthour - 8;
$locmin = $stmin/60; //in hours
if($sthour>14)
$lochour-=2;
$lochour += $locmin;
}
return $lochour;
}
?>
Check the bellow code, that will return the number of Working days
function number_of_working_days($from, $to) {
$workingDays = [1, 2, 3, 4, 5];// date format = (1 = Monday,2 = Tue, ...)
$holidayDays = ['*-12-25', '*-02-14', '2015-12-23']; // variable and fixed holidays
$from = new DateTime($from);
$to = new DateTime($to);
$to->modify('+1 day');
$interval = new DateInterval('P1D');
$days = new DatePeriod($from, $interval, $to);
$no_of_working_days = 0;
foreach ($days as $day) {
if (!in_array($day->format('N'), $workingDays)||in_array($day->format('Y-m-d'), $holidayDays)||in_array($day->format('*-m-d'), $holidayDays)) {continue;}
$working_days++;
}
return $no_of_working_days;
}
echo number_of_working_days('2015-12-01', '2015-09-10');
From that you can easily calculate the Number of Working Hours.
I have created for you this nice class you can use. It requires the nesbot/carbon library (http://carbon.nesbot.com/) and you use it like so:
$calc = new HoursCalculator(
Carbon::createFromFormat("Y-m-d H:i", "2015-10-7 09:00"),
Carbon::createFromFormat("Y-m-d H:i", "2015-10-14 18:00"),
[
"2015-10-13"
]
);
echo $calc->getHours();
Heres the class:
class HoursCalculator {
const LUNCH_HOURS = 2;
protected $start;
protected $end;
protected $holidays;
protected $hoursTotal;
public function __construct(Carbon $start, Carbon $end, $holidays = [])
{
$this->start = $start;
$this->end = $end;
$this->holidays = $holidays;
}
public function getHours()
{
$dayHours = $this->getHoursInADay();
return $this->calculateHours($dayHours);
}
protected function getHoursInADay()
{
$start = $this->start;
$end = Carbon::createFromFormat("Y-m-d H:i", $this->start->format("Y-m-d") . " " . $this->end->format("H:i"));
return $start->diffInHours($end) - self::LUNCH_HOURS;
}
protected function getStartDate()
{
return $this->start->format('Y-m-d');
}
protected function calculateHours($hoursInDay)
{
$start = $this->start->copy()->startOfDay();
$end = $this->end->copy()->endOfDay();
$days = 0;
while($start->lt($end)) {
if (!$this->isHoliday($start) && !$this->isWeekend($start)) {
$days++;
}
$start->addDay(1);
}
return $days * $hoursInDay;
}
protected function isHoliday(Carbon $date)
{
$date->startOfDay();
foreach($this->holidays as $holiday) {
$holiday = Carbon::createFromFormat("Y-m-d", $holiday)->startOfDay();
if ($date->eq($holiday)) {
return true;
}
}
return false;
}
protected function isWeekend(Carbon $date)
{
return $date->isWeekend();
}
}
Hope this helps!
I'm pretty sure I'm overcomplicating this but atm I have no clue how to do it in another way.
I want to create an array which contains the number of a week in a month as a key and the days of this week as the value.
I'm using this function to get all days of a week:
public function getDaysOfWeek($year, $month, $day)
{
$firstMondayThisWeek = new DateTime($year . '/' . $month . '/' . $day, new DateTimeZone("Europe/Berlin"));
$firstMondayThisWeek->modify('tomorrow');
$firstMondayThisWeek->modify('last Monday');
$nextSevenDays = new DatePeriod(
$firstMondayThisWeek,
DateInterval::createFromDateString('+1 day'),
6
);
return $nextSevenDays;
}
And this function to build the array:
public function getWeekAndDays($year, $month)
{
$weeksInMonth = Carbon::createFromDate($year, $month)->endOfMonth()->weekOfMonth;
$weekBegin = Carbon::createFromDate($year, $month)->startOfMonth();
$weeks = [];
for($i=1; $i<=$weeksInMonth; $i++)
{
$collection = new \stdClass();
$collection->week = $i;
$collection->days = $this->getDaysOfWeek($year, $month, $weekBegin->day);
$weekBegin->addWeek(0);
$weeks[] = $collection;
}
return $weeks;
}
For all months except february I'm getting 5 weeks. For February I'm getting 4 weeks and so I'm not able to save the month-overlapping days.
Am I completely wrong here? What is a possible way to solve this task?
My friend I feel your pain, working with calendar data is annoying. Here's a function I wrote a while back that builds an array of weeks and days, separated by months. It's not the cleanest code but it works.
It will start from the date you pass in $today as "Y-m-d" (or default to the current date), then work back to the first week of the current month, start there, and then go forward for $scheduleMonths months building an array indexed first by month and then by week.
It's a bit hard to explain here, but it's self-contained so you can just copy/paste it into your code and then dd() the output to see what it looks like and if it works for you, and modify it from there. There's some formatting you may need to adjust as it was done that way for my specific use case, but the business logic should be sound.
You should be able to extract the number of weeks in a given month from the output (so if that's all you need you can prob simplify this once you confirm it's working).
public function getWeeks($today = null, $scheduleMonths = 6) {
$today = !is_null($today) ? Carbon::createFromFormat('Y-m-d',$today) : Carbon::now();
$startDate = Carbon::instance($today)->startOfMonth()->startOfWeek()->subDay(); // start on Sunday
$endDate = Carbon::instance($startDate)->addMonths($scheduleMonths)->endOfMonth();
$endDate->addDays(6 - $endDate->dayOfWeek);
$epoch = Carbon::createFromTimestamp(0);
$firstDay = $epoch->diffInDays($startDate);
$lastDay = $epoch->diffInDays($endDate);
$week=0;
$monthNum = $today->month;
$yearNum = $today->year;
$prevDay = null;
$theDay = $startDate;
$prevMonth = $monthNum;
$data = array();
while ($firstDay < $lastDay) {
if (($theDay->dayOfWeek == Carbon::SUNDAY) && (($theDay->month > $monthNum) || ($theDay->month == 1))) $monthNum = $theDay->month;
if ($prevMonth > $monthNum) $yearNum++;
$theMonth = Carbon::createFromFormat("Y-m-d",$yearNum."-".$monthNum."-01")->format('F Y');
if (!array_key_exists($theMonth,$data)) $data[$theMonth] = array();
if (!array_key_exists($week,$data[$theMonth])) $data[$theMonth][$week] = array(
'day_range' => '',
);
if ($theDay->dayOfWeek == Carbon::SUNDAY) $data[$theMonth][$week]['day_range'] = sprintf("%d-",$theDay->day);
if ($theDay->dayOfWeek == Carbon::SATURDAY) $data[$theMonth][$week]['day_range'] .= sprintf("%d",$theDay->day);
$firstDay++;
if ($theDay->dayOfWeek == Carbon::SATURDAY) $week++;
$theDay = $theDay->copy()->addDay();
$prevMonth = $monthNum;
}
$totalWeeks = $week;
return array(
'startDate' => $startDate,
'endDate' => $endDate,
'totalWeeks' => $totalWeeks,
'schedule' => $data,
);
}
I hope this helps you at least get started!
Something like this?
function weekOfMonth($date) {
$firstOfMonth = strtotime(date("Y-m-01", $date));
$lastWeekNumber = (int)date("W", $date);
$firstWeekNumber = (int)date("W", $firstOfMonth);
if (12 === (int)date("m", $date)) {
if (1 == $lastWeekNumber) {
$lastWeekNumber = (int)date("W", ($date - (7*24*60*60))) + 1;
}
} elseif (1 === (int)date("m", $date) and 1 < $firstWeekNumber) {
$firstWeekNumber = 0;
}
return $lastWeekNumber - $firstWeekNumber + 1;
}
function weeks($month, $year){
$lastday = date("t", mktime(0, 0, 0, $month, 1, $year));
return weekOfMonth(strtotime($year.'-'.$month.'-'.$lastday));
}
$result = [];
for ($year = 2017; $year < 2020; $year++){
for ($month = 1; $month < 13; $month++) {
$numOfWeeks = weeks($month, $year);
$result[$year][$month]['numOfWeeks'] = $numOfWeeks;
$daysInFirstWeek = 8 - date('N', strtotime($year.'-'.$month.'-01'));
$result[$year][$month]['daysPerWeek']['week_1'] = $daysInFirstWeek;
$startDay = date('d', strtotime('next Monday', strtotime($year.'-'.$month.'-01')));
for ($i = 1; $i < ($numOfWeeks - 1); $i++) {
$startDay += 7;
$result[$year][$month]['daysPerWeek']['week_'.($i+1)] = 7;
}
//last week
$result[$year][$month]['daysPerWeek']['week_'.($i+1)] = date('t', strtotime($year.'-'.$month.'-01')) - $startDay + 1;
}
}
echo json_encode($result)."\n";
Need some logic here:
Need to get day of month date("d")
What I know:
$year = 2013;
$month = 10;
$week_nr_of_month = 3; // from 1 to 6 weeks in month
$day_of_week = 0; // Sunday date("w")
Thanks for logic
Result must be: 13 October
This was fun to figure out.
<?php
$year = 2013;
$month = 10;
$week_nr_of_month = 3; // from 1 to 6 weeks in month
$day_of_week = 0; // Sunday date("w")
$start = new DateTime();
$start->setDate($year, $month, '1');
$end = clone $start;
$end->modify('last day of this month');
$interval = new DateInterval('P1D');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $date) {
if ($date->format('w') == $day_of_week) {
$wom = week_of_month($date->format('Y-m-d'));
if ($week_nr_of_month == $wom) {
echo $date->format('Y-m-d');
}
}
}
function week_of_month($date) {
$dt = new DateTime($date);
$bg = clone $dt;
$bg->modify('first day of this month');
$day_of_first = $bg->format('N');
$day_of_month = $dt->format('j');
return floor(($day_of_first + $day_of_month - 1) / 7) + 1;
}
See it in action
Used this answer for inspiration to get the week number for the date.
strtotime may be of help. Can't test right now, but...
$ordinal = array("first","second","third","fourth","fifth");
$weekdays = array("monday","tuesday","wednesday","thursday","friday","saturday","sunday");
$timestamp = strtotime($year."-".$month." ".$ordinal[$week_nr_of_month]." ".$weekdays[$day_of_week]);
Given the following dates:
6/30/2010 - 7/6/2010
and a static variable:
$h = 7.5
I need to create an array like:
Array ( [2010-06-30] => 7.5 [2010-07-01] => 7.5 => [2010-07-02] => 7.5 => [2010-07-05] => 7.5 => [2010-07-06] => 7.5)
Weekend days excluded.
No, it's not homework...for some reason I just can't think straight today.
For PHP >= 5.3.0, use the DatePeriod class. It's unfortunately barely documented.
$start = new DateTime('6/30/2010');
$end = new DateTime('7/6/2010');
$oneday = new DateInterval("P1D");
$days = array();
$data = "7.5";
/* Iterate from $start up to $end+1 day, one day in each iteration.
We add one day to the $end date, because the DatePeriod only iterates up to,
not including, the end date. */
foreach(new DatePeriod($start, $oneday, $end->add($oneday)) as $day) {
$day_num = $day->format("N"); /* 'N' number days 1 (mon) to 7 (sun) */
if($day_num < 6) { /* weekday */
$days[$day->format("Y-m-d")] = $data;
}
}
print_r($days);
The simplest method:
$start = strtotime('6/30/2010');
$end = strtotime('7/6/2010');
$result = array();
while ($start <= $end) {
if (date('N', $start) <= 5) {
$current = date('m/d/Y', $start);
$result[$current] = 7.5;
}
$start += 86400;
}
print_r($result);
UPDATE: Forgot to skip weekends. This should work now.
This is gnud's answer but as a function (also added an option to exclude the current day from the calculation):
(examples below)
public function getNumberOfDays($startDate, $endDate, $hoursPerDay="7.5", $excludeToday=true)
{
// d/m/Y
$start = new DateTime($startDate);
$end = new DateTime($endDate);
$oneday = new DateInterval("P1D");
$days = array();
/* Iterate from $start up to $end+1 day, one day in each iteration.
We add one day to the $end date, because the DatePeriod only iterates up to,
not including, the end date. */
foreach(new DatePeriod($start, $oneday, $end->add($oneday)) as $day) {
$day_num = $day->format("N"); /* 'N' number days 1 (mon) to 7 (sun) */
if($day_num < 6) { /* weekday */
$days[$day->format("Y-m-d")] = $hoursPerDay;
}
}
if ($excludeToday)
array_pop ($days);
return $days;
}
And to use it:
$date1 = "2012-01-12";
$date2 = date('Y-m-d'); //today's date
$daysArray = getNumberOfDays($date1, $date2);
echo 'hours: ' . array_sum($daysArray);
echo 'days: ' . count($daysArray);
This is OOP approach, just in case. It returns an array with all of dates, except the weekends days.
class Date{
public function getIntervalBetweenTwoDates($startDate, $endDate){
$period = new DatePeriod(
new DateTime($startDate),
new DateInterval('P1D'),
new DateTime($endDate)
);
$all_days = array();$i = 0;
foreach($period as $date) {
if ($this->isWeekend($date->format('Y-m-d'))){
$all_days[$i] = $date->format('Y-m-d');
$i++;
}
}
return $all_days;
}
public function isWeekend($date) {
$weekDay = date('w', strtotime($date));
if (($weekDay == 0 || $weekDay == 6)){
return false;
}else{
return true;
}
}
}
$d = new Date();
var_dump($d->getIntervalBetweenTwoDates('2015-08-01','2015-08-08'));