find out how many weekend in a date range - php

for example I have two dates 2015-10-28 and 2015-12-31. from these I want to know how many saturday and sunday in that given date range. I can find the diff between that dates but I can't find how many weekends.
anyone ever made this?
here is my current code:
function createDateRange($maxDate, $cell, $lead, $offArray = array()){
$dates = [];
--$cell;
--$lead;
$edate = date('Y-m-d', strtotime($maxDate." -$lead day"));
$sdate = date('Y-m-d', strtotime($edate." -$cell day"));
$start = new DateTime($sdate);
$end = new DateTime($edate);
$end = $end->modify('+1 day');
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($start, $interval, $end);
foreach($period as $d){
$dt = $d->format('Y-m-d');
if(!in_array($dt, $dates)){
$dates[] = $dt;
}
}
return $dates;
}
basically I want to add sat+sun count to the date range.

The trick is to use an O(1)-type algorithm to solve this.
Given your starting date, move to the first Saturday. Call that from
Given your ending date, move back to the previous Friday. Call that to
Unless you have an edge case (where to is less than from), compute (to - from) * 2 / 7 as the number of weekend days, and add that to any weekend days passed over in steps (1) and (2).
This is how I do it in production, although generalised for arbitrary weekend days.

Use this function:
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);
}
The function call to get dates for all Sunday's in year 2015:
$dateArr = getDateForSpecificDayBetweenDates('2015-01-01', '2015-12-31', 0);
print "<pre>";
print_r($dateArr);

//周日0 周一1 .....
$data = 4;//周四
$t1 ='2015-10-28';
$t2 = '2015-12-31';
$datetime1 = date_create($t1);
$datetime2 = date_create($t2);
$interval = date_diff($datetime1, $datetime2);
$day = $interval->format('%a');
$result = ($day)/7;
$start = getdate(strtotime($t1))['wday'];
$end = getdate(strtotime($t2))['wday'];
if($data>=$start && $data<=$end){
echo floor($result)+1;
}else{
echo floor($result);
}

Related

find cout of specific day between two date php without using any loop?

I need to find out count of a specific Day between two date.
I can do this by using loop between two date, but if there is difference of 10 years(suppose) between date loop will run 10*365 times.
Is any easier way to do this?
Thanks in advance
function countDays($day, $start, $end)
{
$start = strtotime($start);
$end = strtotime($end);
$datediff = $end - $start;
$days = floor($datediff / (60 * 60 * 24));
//get the day of the week for start and end dates (0-6)
$w = array( date('w', $start ), date('w', $end) );
//get partial week day count
if ($w[0] < $w[1])
{
$partialWeekCount = ($day >= $w[0] && $day <= $w[1]);
}else if ($w[0] == $w[1])
{
$partialWeekCount = $w[0] == $day;
}else
{
$partialWeekCount = ($day >= $w[0]
$day <= $w[1]);
}
//first count the number of complete weeks, then add 1 if $day falls in a partial week.
return intval($days / 7) + $partialWeekCount;
}
Function Call - countDays( 5, "2017-04-14", "2017-04-21")
You are looking for date_diff() function. The date_diff() function returns the difference between two DateTime objects.
<?php
$date1=date_create("2013-03-15");
$date2=date_create("2013-12-12");
$diff=date_diff($date1,$date2);
echo $diff->format("%R%a days");
?>
To find occurrence of specific day (for eg: Sunday). Please note: I have used 7 for Sunday. You can use 1 for Monday, 2 for Tuesday and so on
$cnt = 0;
$start = new DateTime("2013-03-15");
$end = new DateTime("2013-12-12");
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt)
{
if ($dt->format('N') == 7)
{
$cnt++;
}
}
echo $cnt;

How to get start and end date of months of a given range of date in php

I am using following codes to display start and end dates of current month.
function firstOfMonth() {
return date("m/d/Y", strtotime(date('m').'/01/'.date('Y').' 00:00:00'));
}
function lastOfMonth() {
return date("m/d/Y", strtotime('-1 second',strtotime('+1 month',strtotime(date('m').'/01/'.date('Y').' 00:00:00'))));
}
$date_start = firstOfMonth();
$date_end = lastOfMonth();
echo $date_start;
echo $date_end;
Question: How to get start and end dates of all months in a range of date given
For Eg:
function daterange($startdate,$enddate)
{
...
...
...
}
Expected result be array of start and end dates of each month between date range of $startdate and $enddate.
Help me how to do this....
<?php
//Function to return out start and end dates of all months in a date range given
function rent_range($start_date, $end_date)
{
$start_date = date("m/d/Y", strtotime($start_date));
$end_date = date("m/d/Y", strtotime($end_date));
$start = strtotime($start_date);
$end = strtotime($end_date);
$month = $start;
$months[] = date('Y-m', $start);
while($month < $end) {
$month = strtotime("+1 month", $month);
$months[] = date('Y-m', $month);
}
foreach($months as $mon)
{
$mon_arr = explode( "-", $mon);
$y = $mon_arr[0];
$m = $mon_arr[1];
$start_dates_arr[] = date("m/d/Y", strtotime($m.'/01/'.$y.' 00:00:00'));
$end_dates_arr[] = date("m/d/Y", strtotime('-1 minute', strtotime('+1 month',strtotime($m.'/01/'.$y.' 00:00:00'))));
}
//to remove first month in start date and add our start date as first date
array_shift($start_dates_arr);
array_pop($start_dates_arr);
array_unshift($start_dates_arr, $start_date);
//To remove last month in end date and add our end date as last date
array_pop($end_dates_arr);
array_pop($end_dates_arr);
array_push($end_dates_arr, $end_date);
$result['start_dates'] = $start_dates_arr;
$result['end_dates'] = $end_dates_arr;
return $result;
}
$start_date = '2011-07-29';
$end_date = '2012-03-31';
$res = rent_range($start_date, $end_date);
echo "<pre>";
print_r($res);
echo "</pre>";
?>
My Above Function will give the month range display of dates within a given range.
This function would be useful for monthly rent calculation as indian tradition.
It may help some one else....
Have a look at date function and scroll to format character t which gives you the number of days. Start date will always be 1 :-)
Doing this in a loop for the number of months between the two dates and storing the values in an array is up to you
function firstAndLast($d=''){
$d = $d?$d:time();
$f = mktime(0,0,0,date("n",$d),1,date("Y",$d));
$l = mktime(0,0,0,date("n",$d),date("t",$d),date("Y",$d));
return array($f,$l);
}
list($first,$last) = firstAndLast();
echo date("d/m/Y",$first)." ($first) - ".date("d/m/Y",$last)." ($last)";
You can pass a timestamp to the function or leave it blank and it will pick up the current time

PHP- Display days weekly by giving 2 dates

I'd like display dates by week number between giving 2 dates like example below. Is this possible in PHP?
if the dates are 2010-12-01 thru 2010-12-19, it will display it as follows.
week-1
2010-12-01
2010-12-02
2010-12-03
2010-12-04
2010-12-05
2010-12-06
2010-12-07
week-2
2010-12-08
2010-12-09
2010-12-10
2010-12-11
2010-12-12
2010-12-13
2010-12-14
week-3
2010-12-15
2010-12-16
2010-12-17
2010-12-18
2010-12-19
and so on...
I use mysql. It has startdate end enddate fields.
thank you in advance.
I can get how many weeks in those giving 2 dates and display them using a
datediff('ww', '2010-12-01', '2010-12-19', false); I found on the internet.
And I can display dates between two dates as follows. But I am having trouble grouping them by week.
$sdate = "2010-12-01";
$edate = "2010-12-19";
$days = getDaysInBetween($sdate, $edate);
foreach ($days as $val)
{
echo $val;
}
function getDaysInBetween($start, $end) {
// Vars
$day = 86400; // Day in seconds
$format = 'Y-m-d'; // Output format (see PHP date funciton)
$sTime = strtotime($start); // Start as time
$eTime = strtotime($end); // End as time
$numDays = round(($eTime - $sTime) / $day) + 1;
$days = array();
// Get days
for ($d = 0; $d < $numDays; $d++) {
$days[] = date($format, ($sTime + ($d * $day)));
}
// Return days
return $days;
}
New answer.
$current_date = strtotime('2010-12-01');
$end_date = strtotime('2010-12-19');
$day_count = 0;
$current_week = null;
do {
if ((int)($day_count / 7) + 1 != $current_week) {
$current_week = (int)($day_count / 7) + 1;
echo 'week-'.$current_week.'<br />';
}
echo date('Y-m-d', $current_date).'<br />';
$current_date = strtotime('+1 day', $current_date);
$day_count ++;
} while ($current_date <= $end_date);
You will definitely need this: Simplest way to increment a date in PHP?. Write a forloop and increment the day every time. You will also need the DateTime class and functions as date. Indeed asking for date('W', yourDateHere) is a nice idea.
You will get something like this (pseudocode)
$startDate;
$endDate;
$nrOfDays = dateDiffInDays($endDate, $startDate);
$currentWeek = date('W',$startDate);
for($i = 0; $i < $nrOfDays; $i++)
{
$newDay = date('+$i day', $startDate); // get the incremented day
$newWeek = date('W', $newDay); // get the week of the new day
if($newWeek != $currentWeek) // check if we must print the new week, or if we are still in the current
print $newWeek;
print $newDay; // print the day
}
Hope this helps. Good luck.
Tools sufficient to do the job:
strtotime('2010-11-23') - to get a timestamp from a date
strtotime('+1 day', $someTimestamp) - to get the next day
date('W', $someTimestamp) - to get the week number (if you want to group by ISO week number)
array_chunk($orderedListOfSuccessiveDates, 7) - to split in groups of seven days (if you don't want to group by ISO week number)
Warning: Never, ever increment days by adding 86400 to the timestamp! That is the easiest way to break everything when Daylight Saving comes along. Either use the strtotime function or the DateTime class.
Here you go. Although this is with weeks starting on sundays (just change it to monday if need be). And it doesnt work if the dates arent in the same year. But it should be pretty easy to fix that. If not_same_year then ...
$start_date = mktime(0, 0, 0, 12, 01, 2010);
$start_date_week_number = (int) date("W", $start_date);
$end_date = mktime(0, 0, 0, 12, 19, 2010);
$end_date_week_number = (int) date("W", $end_date);
$n = $start_date_week_number;
$w = 1;
$date = $start_date;
while($n <= $end_date_week_number) {
echo("<strong>Week " . $w . "</strong><br />");
$s = 0;
$e = 6;
if($n == $start_date_week_number) $s = (int) date("w", $start_date);
elseif($n == $end_date_week_number) $e = (int) date("w", $end_date);
while($s <= $e) {
echo(date("j-m-y", $date) . "<br />");
$c_date = getdate($date);
$date = mktime($c_date['hours'], $c_date['minutes'], $c_date['seconds'], $c_date['mon'], $c_date['mday'] + 1, $c_date['year']);
$s++;
}
$n++; $w++;
}
DEMO HERE
Edit: just fixed it when I realized you wanted to count the weeks (not get the actual week number)...
$startDate = new DateTime('2010-01-01');
$endDate = new DateTime('2010-01-14');
$weeksDays = getWeeksDaysBetween($startDate, $endDate);
foreach($weeksDays as $week => $days)
{
echo "Week $week<ul>";
foreach($days as $day){
echo "<li>$day</li>";
}
echo "</ul>";
}
function getWeeksDaysBetween($startDate, $endDate)
{
$weeksDays = array();
$dateDiff = $endDate->diff($startDate);
$fullDays = $dateDiff->d;
$numWeeks = floor($fullDays / 7) + 1;
$weeksDays[1][] = $startDate->format('Y-m-d');
for ($i = 1; $i <= $fullDays; $i++)
{
$weekNum = floor($i / 7) + 1;
$dateInterval = DateInterval::createFromDateString("1 day");
$weeksDays[$weekNum][] = $startDate->add($dateInterval)->format('Y-m-d');
}
return $weeksDays;
}

Elegant way to get the count of months between two dates?

Let's assume I have two dates in variables, like
$date1 = "2009-09-01";
$date2 = "2010-05-01";
I need to get the count of months between $date2 and $date1($date2 >= $date1). I.e. i need to get 8.
Is there a way to get it by using date function, or I have to explode my strings and do required calculations?
Thanks.
For PHP >= 5.3
$d1 = new DateTime("2009-09-01");
$d2 = new DateTime("2010-05-01");
var_dump($d1->diff($d2)->m); // int(4)
var_dump($d1->diff($d2)->m + ($d1->diff($d2)->y*12)); // int(8)
DateTime::diff returns a DateInterval object
If you don't run with PHP 5.3 or higher, I guess you'll have to use unix timestamps :
$d1 = "2009-09-01";
$d2 = "2010-05-01";
echo (int)abs((strtotime($d1) - strtotime($d2))/(60*60*24*30)); // 8
But it's not very precise (there isn't always 30 days per month).
Last thing : if those dates come from your database, then use your DBMS to do this job, not PHP.
Edit: This code should be more precise if you can't use DateTime::diff or your RDBMS :
$d1 = strtotime("2009-09-01");
$d2 = strtotime("2010-05-01");
$min_date = min($d1, $d2);
$max_date = max($d1, $d2);
$i = 0;
while (($min_date = strtotime("+1 MONTH", $min_date)) <= $max_date) {
$i++;
}
echo $i; // 8
Or, if you want the procedural style:
$date1 = new DateTime("2009-09-01");
$date2 = new DateTime("2010-05-01");
$interval = date_diff($date1, $date2);
echo $interval->m + ($interval->y * 12) . ' months';
UPDATE: Added the bit of code to account for the years.
Or a simple calculation would give :
$numberOfMonths = abs((date('Y', $endDate) - date('Y', $startDate))*12 + (date('m', $endDate) - date('m', $startDate)))+1;
Accurate and works in all cases.
This is another way to get the number of months between two dates:
// Set dates
$dateIni = '2014-07-01';
$dateFin = '2016-07-01';
// Get year and month of initial date (From)
$yearIni = date("Y", strtotime($dateIni));
$monthIni = date("m", strtotime($dateIni));
// Get year an month of finish date (To)
$yearFin = date("Y", strtotime($dateFin));
$monthFin = date("m", strtotime($dateFin));
// Checking if both dates are some year
if ($yearIni == $yearFin) {
$numberOfMonths = ($monthFin-$monthIni) + 1;
} else {
$numberOfMonths = ((($yearFin - $yearIni) * 12) - $monthIni) + 1 + $monthFin;
}
I use this:
$d1 = new DateTime("2009-09-01");
$d2 = new DateTime("2010-09-01");
$months = 0;
$d1->add(new \DateInterval('P1M'));
while ($d1 <= $d2){
$months ++;
$d1->add(new \DateInterval('P1M'));
}
print_r($months);
Using DateTime, this will give you a more accurate solution for any amount of months:
$d1 = new DateTime("2011-05-14");
$d2 = new DateTime();
$d3 = $d1->diff($d2);
$d4 = ($d3->y*12)+$d3->m;
echo $d4;
You would still need to handle the leftover days $d3->d if your real world problem is not as simple and cut and dry as the original question where both dates are on the first of the month.
This is a simple method I wrote in my class to count the number of months involved into two given dates :
public function nb_mois($date1, $date2)
{
$begin = new DateTime( $date1 );
$end = new DateTime( $date2 );
$end = $end->modify( '+1 month' );
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($begin, $interval, $end);
$counter = 0;
foreach($period as $dt) {
$counter++;
}
return $counter;
}
In case the dates are part of a resultset from a mySQL query, it is much easier to use the TIMESTAMPDIFF function for your date calculations and you can specify return units eg. Select TIMESTAMPDIFF(MONTH, start_date, end_date)months_diff from table_name
strtotime is not very precise, it makes an approximate count, it does not take into account the actual days of the month.
it's better to bring the dates to a day that is always present in every month.
$date1 = "2009-09-01";
$date2 = "2010-05-01";
$d1 = mktime(0, 0, 1, date('m', strtotime($date1)), 1, date('Y', strtotime($date1)));
$d2 = mktime(0, 0, 1, date('m', strtotime($date2)), 1, date('Y', strtotime($date2)));
$total_month = 0;
while (($d1 = strtotime("+1 MONTH", $d1)) <= $d2) {
$total_month++;
}
echo $total_month;
I have used this and works in all conditions
$fiscal_year = mysql_fetch_row(mysql_query("SELECT begin,end,closed FROM fiscal_year WHERE id = '2'"));
$date1 = $fiscal_year['begin'];
$date2 = $fiscal_year['end'];
$ts1 = strtotime($date1);
$ts2 = strtotime($date2);
$te=date('m',$ts2-$ts1);
echo $te;

Return Array of Months Between and Inclusive of Start and End Dates

I have two dates - a start date and an end date. I need to return an array of months ('Y-m' format) which includes every month between start and end date, as well as the months that those dates are in. I've tried:
$start = strtotime('2010-08-20');
$end = strtotime('2010-09-15');
$month = $start;
while($month <= $end) {
$months[] = date('Y-m', $month);
$month = strtotime("+1 month", $month);
}
The problem is that, in the above example, it only adds '2010-08' to the array, and not '2010-09'. I feel like the solution should be obvious, but I just can't see it.
Note that this should take into account situations like:
$start = strtotime('2010-08-20');
$end = strtotime('2010-08-21');
// should return '2010-08'
$start = strtotime('2010-08-20');
$end = strtotime('2010-09-01');
// should return '2010-08,2010-09'
$start = strtotime('2010-08-20');
$end = strtotime('2010-10-21');
// should return '2010-08,2010-09,2010-10'
Also, the version of PHP on my host is 5.2.6 so it has to work within those confines.
The solution I used was based on the answer below re. setting $start to the first day of the month. However I couldn't get it working with just the strtotime() and instead had to use another function I found on the web.
function firstDayOfMonth($uts=null)
{
$today = is_null($uts) ? getDate() : getDate($uts);
$first_day = getdate(mktime(0,0,0,$today['mon'],1,$today['year']));
return $first_day[0];
}
$start = strtotime('2010-08-20');
$end = strtotime('2010-09-15');
$month = firstDayOfMonth($start);
while($month <= $end) {
$months[] = date('Y-m', $month);
$month = strtotime("+1 month", $month);
}
The problem is that $start day is bigger than end day, so after you add month to start its bigger than end, solution is to use first day of the month, like 2010-08-01 so after you add +1 month you will get at least equal $end ;)
This should do what you need.
$start = strtotime('2010-08-20');
$end = strtotime('2010-10-15');
$month = $start;
$months[] = date('Y-m', $start);
while($month <= $end) {
$month = strtotime("+1 month", $month);
$months[] = date('Y-m', $month);
}
Add a
if( date('d',$month) != date('d',$end) )
$months[] = date('Y-m', $month);
below the loop. This means, you add the last month if its only partially contained in $end (days are different: last difference is smaller than a month).
rbo

Categories