I have three date ranges in mysql table as follow
from 2013-09-29 to 2013-10-02
from 2013-10-14 to 2013-10-16
from 2013-10-28 to 2013-11-05
I want to count only days that occur in Month of October, for example from first range (2013-09-29 to 2013-10-02) I should get difference of two days (1st and 2nd October) , and it should ignore days from September month, Finally i want to count total days in a given month from above date ranges.
Can it be done from direct mysql query. or any short PHP logic.
here is my table structure
id,employee_id,leave_start,leave_to
I am looking for a method some thing like
function countLeaves($employee_id,$month)
{
// code
return $numberOfLeaves
}
You need to calculate the first day of the month 2013-10-01 and the last day of the month 2013-10-31 and then you could use a query like this:
SELECT
DATEDIFF(
LEAST(d_end, '2013-10-31'),
GREATEST(d_start, '2013-10-01'))+1 days
FROM
ranges
WHERE
d_start<='2013-10-31' AND d_end>='2013-10-01'
Please see fiddle here.
function getAllDates($fromDate, $toDate,$rejectmonth)
{
if(!$fromDate || !$toDate ) {return false;}
$dateMonthYearArr = array();
$fromDateTS = strtotime($fromDate);
$toDateTS = strtotime($toDate);
for ($currentDateTS = $fromDateTS; $currentDateTS <= $toDateTS; $currentDateTS += (60 * 60 * 24))
{
if($rejectmonth == date("m",$currentDateTS))
continue;
$currentDateStr = date("Y-m-d",$currentDateTS);
$dateMonthYearArr[] = $currentDateStr;
}
return $dateMonthYearArr;
}
use this function will return the array dates which are in the date ranges.
getAllDates('2013-09-10','2013-19-10',10);
$month = strtotime(date('Y-m-01', time()));
$daysCount = (int)(time() - $month) / (24 * 3600);
and if you need to check from any date to any date:
/**
* #var $dateFrom string Date to count from,
* you can use date('Y-m-01') as start of current month
* #var $dateTo string End of period date, example: '2013-09-05'
**/
function getDaysCount($dateFrom, $dateTo)
{
return (int)(strtotime($dateTo) - strtotime($dateFrom)) / (24 * 3600);
}
Related
I'm trying to write a function to calculate the next date that a piece of equipment needs to be checked. I'm using the code below (it's incomplete.)
function get_next_check(){
$today = date(get_option('date_format'));
$first_check = types_get_field_meta_value( 'first_check', $post_id );
// Interval is a number of weeks- ie. month = 4, year = 52
$interval = types_get_field_meta_value( 'interval', $post_id );
// Calculate the next date after today that the check needs to be performed
$next_check = ;
return $next_check;
}
add_shortcode( 'next_check', 'get_next_check' );
I'm guessing I need to create an array of all possible dates, and compare each to today's date, only returning the next one?
Assuming that $first_check is a string with the date in it, and you want the function to return the same, something like this might work:
$week = 60 * 60 * 24 * 7; // number of seconds in a week
$next_check = strtotime($first_check);
while ($next_check < time()) {
$next_check += $week * $interval; // advance the check time by the desired interval
}
return date(get_option('date_format'), $next_check);
You can eliminate your initialization of the $today variable with this.
You can achieve this on the proposed by Greg Schmidt , or alternatively by doing:
// Calculate the next date after today that the check needs to be performed
$next_check = date(get_option('date_format'), strtotime($today." ".$interval." weeks"));
I have a table Orders that holds information about the rental date range and the price for a car rental.
The price is given by:
SELECT ROUND((points * (SELECT DATEDIFF('$dateTo', '$dateFrom'))) * 0.95) AS price
$dateTo and $dateFrom are PHP variables that holds the value of a given date range by the user. In others words:
$dateTo = $_POST['date-to'];
$dateFrom = $_POST['date-from'];
So for each day you are given 5% off from the rental price, but I also want to check if the date range goes across a Saturday or a Sunday. If the rental is from Friday to Monday, I want to add an extra 10 points to the total price because the date range includes a Saturday.
Is this possible?
You could use a stored Procedure for that purpose where your query may be nested inside of a Loop to check if it' s Weekday or not.
Alternatively, You could check if the range of Dates has a Weekend within it using PHP like so:
<?php
/**
* FUNCTION THAT CHECKS IF A WEEKEND EXISTS BETWEEN 2 GIVEN DATES
* #param string $startDate
* #param string $endDate
* #return boolean
*/
function dateRangeContainsWeekend($startDate, $endDate) {
$tsDate = strtotime($startDate);
$diff = date_diff(date_create($startDate), date_create($endDate));
$dDiff = $diff->days;
if ($dDiff > 0) {
for ($i = 0; $i < $dDiff; $i++) {
$timeDiff = 24 * 60 * 60 * $i;
$sDate = $tsDate + $timeDiff;
$weekDay = date('w', $sDate);
if (($weekDay == 0 || $weekDay == 6)) {
return ($weekDay == 0 || $weekDay == 6);
}
}
}
return false;
}
// TESTS - - - -
$d1 = "2016-05-02";
$d2 = "2016-05-10";
var_dump( dateRangeContainsWeekend($d1, $d2) ); // DUMPS true
// NOW; IF YOU KNOW THAT THE GIVEN DATES CONTAIN A WEEKEND,
// YOU MAY MODIFY YOUR QUERY TO REFLECT YOUR DESIRES
$factor = "0.95"; //CHOOSE YOUR FACTOR HERE...
$sql = "SELECT ROUND((points * (SELECT DATEDIFF('$dateTo', '$dateFrom'))) * $factor) AS price";
This question already has answers here:
Elegant way to get the count of months between two dates?
(10 answers)
Closed 3 years ago.
Is there any way to find the month difference in PHP? I have the input of from-date 2003-10-17 and to-date 2004-03-24. I need to find how many months there are within these two days. Say if 6 months, I need the output in months only. Thanks for guiding me for day difference.
I find the solution through MySQL but I need it in PHP. Anyone help me, Thanks in advance.
The easiest way without reinventing the wheel. This'll give you the full months difference. I.e. the below two dates are almost 76 months apart, but the result is 75 months.
date_default_timezone_set('Asia/Tokyo'); // you are required to set a timezone
$date1 = new DateTime('2009-08-12');
$date2 = new DateTime('2003-04-14');
$diff = $date1->diff($date2);
echo (($diff->format('%y') * 12) + $diff->format('%m')) . " full months difference";
After testing tons of solutions, putting all in a unit test, this is what I come out with:
/**
* Calculate the difference in months between two dates (v1 / 18.11.2013)
*
* #param \DateTime $date1
* #param \DateTime $date2
* #return int
*/
public static function diffInMonths(\DateTime $date1, \DateTime $date2)
{
$diff = $date1->diff($date2);
$months = $diff->y * 12 + $diff->m + $diff->d / 30;
return (int) round($months);
}
For example it will return (test cases from the unit test):
01.11.2013 - 30.11.2013 - 1 month
01.01.2013 - 31.12.2013 - 12 months
31.01.2011 - 28.02.2011 - 1 month
01.09.2009 - 01.05.2010 - 8 months
01.01.2013 - 31.03.2013 - 3 months
15.02.2013 - 15.04.2013 - 2 months
01.02.1985 - 31.12.2013 - 347 months
Notice: Because of the rounding it does with the days, even a half of a month will be rounded, which may lead to issue if you use it with some cases. So DO NOT USE it for such cases, it will cause you issues.
For example:
02.11.2013 - 31.12.2013 will return 2, not 1 (as expected).
I just wanted to add this if anyone is looking for a simple solution that counts each touched-upon month in stead of complete months, rounded months or something like that.
// Build example data
$timeStart = strtotime("2003-10-17");
$timeEnd = strtotime("2004-03-24");
// Adding current month + all months in each passed year
$numMonths = 1 + (date("Y",$timeEnd)-date("Y",$timeStart))*12;
// Add/subtract month difference
$numMonths += date("m",$timeEnd)-date("m",$timeStart);
echo $numMonths;
Wow, way to overthink the problem... How about this version:
function monthsBetween($startDate, $endDate) {
$retval = "";
// Assume YYYY-mm-dd - as is common MYSQL format
$splitStart = explode('-', $startDate);
$splitEnd = explode('-', $endDate);
if (is_array($splitStart) && is_array($splitEnd)) {
$difYears = $splitEnd[0] - $splitStart[0];
$difMonths = $splitEnd[1] - $splitStart[1];
$difDays = $splitEnd[2] - $splitStart[2];
$retval = ($difDays > 0) ? $difMonths : $difMonths - 1;
$retval += $difYears * 12;
}
return $retval;
}
NB: unlike several of the other solutions, this doesn't depend on the date functions added in PHP 5.3, since many shared hosts aren't there yet.
http://www.php.net/manual/en/datetime.diff.php
This returns a DateInterval object which has a format method.
$datetime1 = date_create('2009-10-11');
$datetime2 = date_create('2013-1-13');
$interval = date_diff($datetime1, $datetime2);
echo $interval->format('%a day %m month %y year');
// get year and month difference
$a1 = '20170401';
$a2 = '20160101'
$yearDiff = (substr($a1, 0, 4) - substr($a2, 0, 4));
$monthDiff = (substr($a1, 4, 2) - substr($a2, 4, 2));
$fullMonthDiff = ($yearDiff * 12) + $monthDiff;
// fullMonthDiff = 16
This is my enhanced version of #deceze answer:
/**
* #param string $startDate
* Current date is considered if empty string is passed
* #param string $endDate
* Current date is considered if empty string is passed
* #param bool $unsigned
* If $unsigned is true, difference is always positive, otherwise the difference might be negative
* #return int
*/
public static function diffInFullMonths($startDate, $endDate, $unsigned = false)
{
$diff = (new DateTime($startDate))->diff(new DateTime($endDate));
$reverse = $unsigned === true ? '' : '%r';
return ((int) $diff->format("{$reverse}%y") * 12) + ((int) $diff->format("{$reverse}%m"));
}
The best way.
function getIntervals(DateTime $from, DateTime $to)
{
$intervals = [];
$startDate = $from->modify('first day of this month');
$endDate = $to->modify('last day of this month');
while($startDate < $endDate){
$firstDay = $startDate->format('Y-m-d H:i:s');
$startDate->modify('last day of this month')->modify('+1 day');
$intervals[] = [
'firstDay' => $firstDay,
'lastDay' => $startDate->modify('-1 second')->format('Y-m-d H:i:s'),
];
$startDate->modify('+1 second');
}
return $intervals;
}
$dateTimeFirst = new \DateTime('2013-01-01');
$dateTimeSecond = new \DateTime('2013-03-31');
$interval = getIntervals($dateTimeFirst, $dateTimeSecond);
print_r($interval);
Result:
Array
(
[0] => Array
(
[firstDay] => 2013-01-01 00:00:00
[lastDay] => 2013-01-31 23:59:59
)
[1] => Array
(
[firstDay] => 2013-02-01 00:00:00
[lastDay] => 2013-02-28 23:59:59
)
[2] => Array
(
[firstDay] => 2013-03-01 00:00:00
[lastDay] => 2013-03-31 23:59:59
)
)
In my case I needed to count full months and day leftovers as month as well to build a line chart labels.
/**
* Calculate the difference in months between two dates
*
* #param \DateTime $from
* #param \DateTime $to
* #return int
*/
public static function diffInMonths(\DateTime $from, \DateTime $to)
{
// Count months from year and month diff
$diff = $to->diff($from)->format('%y') * 12 + $to->diff($from)->format('%m');
// If there is some day leftover, count it as the full month
if ($to->diff($from)->format('%d') > 0) $diff++;
// The month count isn't still right in some cases. This covers it.
if ($from->format('d') >= $to->format('d')) $diff++;
}
<?php
# end date is 2008 Oct. 11 00:00:00
$_endDate = mktime(0,0,0,11,10,2008);
# begin date is 2007 May 31 13:26:26
$_beginDate = mktime(13,26,26,05,31,2007);
$timestamp_diff= $_endDate-$_beginDate +1 ;
# how many days between those two date
$days_diff = $timestamp_diff/2635200;
?>
Reference: http://au.php.net/manual/en/function.mktime.php#86916
function monthsDif($start, $end)
{
// Assume YYYY-mm-dd - as is common MYSQL format
$splitStart = explode('-', $start);
$splitEnd = explode('-', $end);
if (is_array($splitStart) && is_array($splitEnd)) {
$startYear = $splitStart[0];
$startMonth = $splitStart[1];
$endYear = $splitEnd[0];
$endMonth = $splitEnd[1];
$difYears = $endYear - $startYear;
$difMonth = $endMonth - $startMonth;
if (0 == $difYears && 0 == $difMonth) { // month and year are same
return 0;
}
else if (0 == $difYears && $difMonth > 0) { // same year, dif months
return $difMonth;
}
else if (1 == $difYears) {
$startToEnd = 13 - $startMonth; // months remaining in start year(13 to include final month
return ($startToEnd + $endMonth); // above + end month date
}
else if ($difYears > 1) {
$startToEnd = 13 - $startMonth; // months remaining in start year
$yearsRemaing = $difYears - 2; // minus the years of the start and the end year
$remainingMonths = 12 * $yearsRemaing; // tally up remaining months
$totalMonths = $startToEnd + $remainingMonths + $endMonth; // Monthsleft + full years in between + months of last year
return $totalMonths;
}
}
else {
return false;
}
}
Here's a quick one:
$date1 = mktime(0,0,0,10,0,2003); // m d y, use 0 for day
$date2 = mktime(0,0,0,3,0,2004); // m d y, use 0 for day
echo round(($date2-$date1) / 60 / 60 / 24 / 30);
I have a variable $ node-> field_work_start [0] ['view'] which denotes the date of birth. To follow up I want to do a background check on the fact that this date is included in the next period then 10 days from the current date. If true then x = 1, false x = 0. Help please with code PHP.
It sounds like you are given a DATETIME with $node->field_work_start[0]['view'] correct? If this is the case, we're going to convert it to a UNIX timestamp to make things a little bit easier. In this example we will assume your date is stored in M d, Y form.
This little code should work well for you!
<?php
class Node
{
// For sake of keeping things similar to your environment
var $field_work_start = array();
}
/**
* checkBirthday function
*
* The function will check a birth date
* and see if it is in the range of specified
* days.
*
* #param $birthday
* Birth date parameter. Assumed to be in M d, Y form
* #param $days
* The range of days to check where the birthday is
* #return int
* 0 if the birthday is _NOT_ within the proper range
* 1 if the birthday _IS_ within the proper range
*/
function checkBirthday($birthday,$days)
{
// Parse out the year of the birthday
$pos = strpos($birthday,",")+2; // Find the comma which separates the year
$today = strtotime(date("M, d")); // Check if day is < Dec. 22. If not, we need to account for next year!
// Check if the birthday is within the range and has not passed!
if($today < strtotime("Dec 22")){
$birthday = substr_replace($birthday,date("Y"),$pos,4); // Replace the year with current year
if(strtotime($birthday) <= strtotime("+".$days." days") && strtotime($birthday) >= time()){
return 1;
}
} else { // Less than 10 days left in our year.. check for January birthdays!
if(!strstr($birthday,"December")){
$birthday = substr_replace($birthday,date("Y")+1,$pos,4); // Replace the year with next year
$year = date("Y")+1;
} else { // Still December?
$birthday = substr_replace($birthday,date("Y"),$pos,4); // Replace the year with current year
$year = date("Y");
}
$day = (date("d")+10)-31; // 10 days from now is...
if((strtotime($birthday) <= strtotime("January ".$day.", ".$year)) && strtotime($birthday) >= strtotime("December 25, 2010")){
return 1;
}
}
return 0;
}
$node[] = new Node;
$node[0]->field_work_start[0] = "January 1, 1970"; // First birthday is _NOT_ within range
$node[1]->field_work_start[0] = "July 20, 1970"; // Second birthday _IS_ within range
for($i=0;$i<count($node);$i++){
if(!checkBirthday($node[$i]->field_work_start[0],10)){
print $node[$i]->field_work_start[0]." is not within the 10 day range.<br /><br />";
} else {
print $node[$i]->field_work_start[0]." is within the 10 day range.<br /><br />";
}
}
unset($node);
?>
It should return this output:
January 1, 1970 is not within the 10 day range.
July 20, 1970 is within the 10 day range.
Good luck!
Regards,
Dennis M.
This question already has answers here:
Elegant way to get the count of months between two dates?
(10 answers)
Closed 3 years ago.
Is there any way to find the month difference in PHP? I have the input of from-date 2003-10-17 and to-date 2004-03-24. I need to find how many months there are within these two days. Say if 6 months, I need the output in months only. Thanks for guiding me for day difference.
I find the solution through MySQL but I need it in PHP. Anyone help me, Thanks in advance.
The easiest way without reinventing the wheel. This'll give you the full months difference. I.e. the below two dates are almost 76 months apart, but the result is 75 months.
date_default_timezone_set('Asia/Tokyo'); // you are required to set a timezone
$date1 = new DateTime('2009-08-12');
$date2 = new DateTime('2003-04-14');
$diff = $date1->diff($date2);
echo (($diff->format('%y') * 12) + $diff->format('%m')) . " full months difference";
After testing tons of solutions, putting all in a unit test, this is what I come out with:
/**
* Calculate the difference in months between two dates (v1 / 18.11.2013)
*
* #param \DateTime $date1
* #param \DateTime $date2
* #return int
*/
public static function diffInMonths(\DateTime $date1, \DateTime $date2)
{
$diff = $date1->diff($date2);
$months = $diff->y * 12 + $diff->m + $diff->d / 30;
return (int) round($months);
}
For example it will return (test cases from the unit test):
01.11.2013 - 30.11.2013 - 1 month
01.01.2013 - 31.12.2013 - 12 months
31.01.2011 - 28.02.2011 - 1 month
01.09.2009 - 01.05.2010 - 8 months
01.01.2013 - 31.03.2013 - 3 months
15.02.2013 - 15.04.2013 - 2 months
01.02.1985 - 31.12.2013 - 347 months
Notice: Because of the rounding it does with the days, even a half of a month will be rounded, which may lead to issue if you use it with some cases. So DO NOT USE it for such cases, it will cause you issues.
For example:
02.11.2013 - 31.12.2013 will return 2, not 1 (as expected).
I just wanted to add this if anyone is looking for a simple solution that counts each touched-upon month in stead of complete months, rounded months or something like that.
// Build example data
$timeStart = strtotime("2003-10-17");
$timeEnd = strtotime("2004-03-24");
// Adding current month + all months in each passed year
$numMonths = 1 + (date("Y",$timeEnd)-date("Y",$timeStart))*12;
// Add/subtract month difference
$numMonths += date("m",$timeEnd)-date("m",$timeStart);
echo $numMonths;
Wow, way to overthink the problem... How about this version:
function monthsBetween($startDate, $endDate) {
$retval = "";
// Assume YYYY-mm-dd - as is common MYSQL format
$splitStart = explode('-', $startDate);
$splitEnd = explode('-', $endDate);
if (is_array($splitStart) && is_array($splitEnd)) {
$difYears = $splitEnd[0] - $splitStart[0];
$difMonths = $splitEnd[1] - $splitStart[1];
$difDays = $splitEnd[2] - $splitStart[2];
$retval = ($difDays > 0) ? $difMonths : $difMonths - 1;
$retval += $difYears * 12;
}
return $retval;
}
NB: unlike several of the other solutions, this doesn't depend on the date functions added in PHP 5.3, since many shared hosts aren't there yet.
http://www.php.net/manual/en/datetime.diff.php
This returns a DateInterval object which has a format method.
$datetime1 = date_create('2009-10-11');
$datetime2 = date_create('2013-1-13');
$interval = date_diff($datetime1, $datetime2);
echo $interval->format('%a day %m month %y year');
// get year and month difference
$a1 = '20170401';
$a2 = '20160101'
$yearDiff = (substr($a1, 0, 4) - substr($a2, 0, 4));
$monthDiff = (substr($a1, 4, 2) - substr($a2, 4, 2));
$fullMonthDiff = ($yearDiff * 12) + $monthDiff;
// fullMonthDiff = 16
This is my enhanced version of #deceze answer:
/**
* #param string $startDate
* Current date is considered if empty string is passed
* #param string $endDate
* Current date is considered if empty string is passed
* #param bool $unsigned
* If $unsigned is true, difference is always positive, otherwise the difference might be negative
* #return int
*/
public static function diffInFullMonths($startDate, $endDate, $unsigned = false)
{
$diff = (new DateTime($startDate))->diff(new DateTime($endDate));
$reverse = $unsigned === true ? '' : '%r';
return ((int) $diff->format("{$reverse}%y") * 12) + ((int) $diff->format("{$reverse}%m"));
}
The best way.
function getIntervals(DateTime $from, DateTime $to)
{
$intervals = [];
$startDate = $from->modify('first day of this month');
$endDate = $to->modify('last day of this month');
while($startDate < $endDate){
$firstDay = $startDate->format('Y-m-d H:i:s');
$startDate->modify('last day of this month')->modify('+1 day');
$intervals[] = [
'firstDay' => $firstDay,
'lastDay' => $startDate->modify('-1 second')->format('Y-m-d H:i:s'),
];
$startDate->modify('+1 second');
}
return $intervals;
}
$dateTimeFirst = new \DateTime('2013-01-01');
$dateTimeSecond = new \DateTime('2013-03-31');
$interval = getIntervals($dateTimeFirst, $dateTimeSecond);
print_r($interval);
Result:
Array
(
[0] => Array
(
[firstDay] => 2013-01-01 00:00:00
[lastDay] => 2013-01-31 23:59:59
)
[1] => Array
(
[firstDay] => 2013-02-01 00:00:00
[lastDay] => 2013-02-28 23:59:59
)
[2] => Array
(
[firstDay] => 2013-03-01 00:00:00
[lastDay] => 2013-03-31 23:59:59
)
)
In my case I needed to count full months and day leftovers as month as well to build a line chart labels.
/**
* Calculate the difference in months between two dates
*
* #param \DateTime $from
* #param \DateTime $to
* #return int
*/
public static function diffInMonths(\DateTime $from, \DateTime $to)
{
// Count months from year and month diff
$diff = $to->diff($from)->format('%y') * 12 + $to->diff($from)->format('%m');
// If there is some day leftover, count it as the full month
if ($to->diff($from)->format('%d') > 0) $diff++;
// The month count isn't still right in some cases. This covers it.
if ($from->format('d') >= $to->format('d')) $diff++;
}
<?php
# end date is 2008 Oct. 11 00:00:00
$_endDate = mktime(0,0,0,11,10,2008);
# begin date is 2007 May 31 13:26:26
$_beginDate = mktime(13,26,26,05,31,2007);
$timestamp_diff= $_endDate-$_beginDate +1 ;
# how many days between those two date
$days_diff = $timestamp_diff/2635200;
?>
Reference: http://au.php.net/manual/en/function.mktime.php#86916
function monthsDif($start, $end)
{
// Assume YYYY-mm-dd - as is common MYSQL format
$splitStart = explode('-', $start);
$splitEnd = explode('-', $end);
if (is_array($splitStart) && is_array($splitEnd)) {
$startYear = $splitStart[0];
$startMonth = $splitStart[1];
$endYear = $splitEnd[0];
$endMonth = $splitEnd[1];
$difYears = $endYear - $startYear;
$difMonth = $endMonth - $startMonth;
if (0 == $difYears && 0 == $difMonth) { // month and year are same
return 0;
}
else if (0 == $difYears && $difMonth > 0) { // same year, dif months
return $difMonth;
}
else if (1 == $difYears) {
$startToEnd = 13 - $startMonth; // months remaining in start year(13 to include final month
return ($startToEnd + $endMonth); // above + end month date
}
else if ($difYears > 1) {
$startToEnd = 13 - $startMonth; // months remaining in start year
$yearsRemaing = $difYears - 2; // minus the years of the start and the end year
$remainingMonths = 12 * $yearsRemaing; // tally up remaining months
$totalMonths = $startToEnd + $remainingMonths + $endMonth; // Monthsleft + full years in between + months of last year
return $totalMonths;
}
}
else {
return false;
}
}
Here's a quick one:
$date1 = mktime(0,0,0,10,0,2003); // m d y, use 0 for day
$date2 = mktime(0,0,0,3,0,2004); // m d y, use 0 for day
echo round(($date2-$date1) / 60 / 60 / 24 / 30);