Laravel 7: Find days and dates between two dates with condition - php

When the user submits a leave application, needs to select the start and end date. But before saving it needs to check is there any holiday or weekly holiday in between two dates. If a holiday or weekly holiday matches then the total number of holidays will be deducted from the total days.
Weekly Holiday:
id
day
working_status
1
Fri
1
Holiday Table: (Model Name: Holiday)
id
date
publication_status
1
2022-05-26
1
Leave Table:
id
start_date
end_date
total_days
1
2022-05-25
2022-05-28
2
Controller:
$leave = new User;
$leave->start_date = $request->start_date;
$leave->end_date = $request->end_date;
//get and convert day name for weekly holiday compare like Fri, Sat etc.
$start_day = date("D", strtotime($request->start_date));
$end_day = date("D", strtotime($request->end_date));
// get and convert date for monthly holiday compare
$start = strtotime($request->start_date);
$end = strtotime($request->end_date);
$diff = $end - $start;
$diff_in_days = floor($diff/(60*60*24)) + 1;
// Suppose Fri is holiday now we have to count how many Fri day in between start and end date.
here need help
$weekly_holidays = WorkingDay::where('working_status', 1)
->get(['day'])->count();
// we have to count how many Monthly holiday in between start and end date. here need help
$monthly_holidays= Holiday::where('publication_status', 1)->get(['date'])->count();
$total_days = $diff_in_days - ($weekly_holidays + $monthly_holidays);
if($request->halfday == 1){
$leave->total_days = 0.5;
}
else{
$leave->total_days = $total_days;
}
Example:
WorkingDay = day = Fri
Holiday = date = 2022-05-26
start_date = 2022-05-25
end_date = 2022-05-28
total_days = 2
// from 25 to 28, the total days are 4, but 26 is a holiday, and 27 is Friday. Holidays can be multiple dates. If there is multiple holidays between the start and end date, it will calculate according to this.

It's actually easier. You don't need to complicate it. Carbon comes to the rescue here.
$startDate = Carbon::parse('start date here');
$endDate = Carbon::parse('date string here');
$weekdays = $startDate->diffInWeekdays($endDate);
This will give you the day difference in weekdays excluding any weekends.
Now whichever database you use, you would have a function to get the day of the week in number where 0 stands for Sunday and 6 for Saturday.
For Postgres, I will give you an example
weekdays_holiday_count = select count(*) from holidays where date_part('dow', date) not in (0, 6) # 0 for Sunday and 6 for Saturday
This query is counting holidays which came on weekdays. I give you the raw query here. however, the point here is to under the magic of the function.
Now you can do the math easily
$weekdays - $weekdays_holiday_count
Make sure to import Carbon\Carbon at the top.

Related

SUM multiple date ranges in mysql query

I have a MySql table 'Products' with three columns:
Date | Product | Qty
My aim is to SUM the qty of each product for every week.
Getting the SUM between two given dates would be easy:
SELECT SUM(qty) FROM products WHERE date >= '2010-01-01' AND date < '2011-01-1'
I can generate a list of weeks in Php using something like:
$today = date('Y-m-d', strtotime('last week Monday'));
$future = date('Y-m-d', strtotime('+90 days'));
$period = new DatePeriod(
new DateTime($today),
new DateInterval('P7D'),
new DateTime($future)
);
foreach ($period as $key => $value) {
$dates .= $value->format('Y-m-d');
}
Is there a MySql query that would work to Group By and SUM by dates? Or would I be better off looping through in Php?
You can use Year() and Week() functions in MySQL, to get the year and week number for a given date. Week() function will return week number from 0 to 53. So, you will be needed to use Year() function alongwith, if you have data spanning over multiple years.
But then, you will be more interested in knowing the start date and end date for the concerned week. This is where we can use a very interesting function DayOfWeek(). It returns the weekday index for a given date (1 = Sunday, 2 = Monday, …, 7 = Saturday)
We can use Date_Add() function using the weekday index value and the actual date value, to determine the starting week date and ending week date for a given date.
Try the following (if the Week starts on Sunday) :
SELECT
DATE_ADD(`date`, INTERVAL(1 - DAYOFWEEK(`date`)) DAY) AS week_start_date,
DATE_ADD(`date`, INTERVAL(7 - DAYOFWEEK(`date`)) DAY) AS week_end_date,
SUM(qty)
FROM
products
GROUP BY week_start_date, week_end_date
If the week starts on Monday, another handy function is WeekDay(). It returns the weekday index for date (0 = Monday, 1 = Tuesday, … 6 = Sunday).
Try the following (if the Week starts on Monday) :
SELECT
DATE_ADD(`date`, INTERVAL(0 - WEEKDAY(`date`)) DAY) AS week_start_date,
DATE_ADD(`date`, INTERVAL(6 - WEEKDAY(`date`)) DAY) AS week_end_date,
SUM(qty)
FROM
products
GROUP BY week_start_date, week_end_date
You can achieve that with a group by like
GROUP BY week(date)
GROUP BY so do
SELECT SUM(qty) FROM products GROUP BY WEEK(date);

Get Interval Night and Day per Day between two dates

I am creating an algorithm that must return two intervals between two dates:
$interval_day (between 6am and 9pm)
$interval_night (between 9pm and 6am)
Currently, I managed to have the overall interval between these two dates for the day. However, I now need a daytime interval and a nighttime interval for the day.
Here is the code I have done to get the interval per day between two dates:
foreach($period as $p => $v){
$day = $v->format('Y-m-d');
$interval = 0;
foreach($rotations as $rotation){
// Get the day of each dates
$date_start = explode(" ", $rotation['date_start'])[0];
$date_end = explode(" ", $rotation['date_end'])[0];
if($date_start == $date_end){
// += interval between the two dates
$interval += strtotime($rotation['date_end']) - strtotime($rotation['date_start']);
}else if($date_start == $day){
// += interval between the start date and midnight
$interval += strtotime($day." 23:59:59") - strtotime($rotation['date_end']);
}else if($date_end == $day){
// += interval between midnight and the end date
$interval += strtotime($rotation['date_end']) - strtotime($day." 00:00:00");
}
}
}
I hope it's clear for you
What I want now is to get 2 intervals instead of one :
1 interval for dates between 6 am and 9 pm as $interval_day
1 interval for dates between 9 pm and 6 am as $interval_night
For exemple:
rotation['date_start'] = 27/07/2018 21:00:00
rotation['date_end'] = 28/07/2018 02:00:00
then
27/07/2018 :
$interval_day = 00:00:00 and $interval_night = 03:00:00
28/07/2018 :
$interval_day = 00:00:00 and $interval_night = 02:00:00
For each day you have to compute 3 overlappings:
overlapping between the interval [date_start time_start,
date_end time_end] for the given day and the interval [date_start 06:00:00, date_end 21:00:00]
overlapping between the interval [date_start time_start, date_end time_end] for the given day and the interval [date_start 00:00:00, date_end 06:00:00]
overlapping between the interval [date_start time_start, date_end time_end) for the given day and the interval [date_start 21:00:00, date_end 23:59:59]
To do that, use the following formula:
overlap = MAX(0,end_1 - start_1 - MAX(0,end_1 - end_2) - MAX(0,start_2 - start_1))
The formula needs integers - i.e. UNIX timestamps.

How to get the last three days excluding holidays (french) and weekdays in SQL or PHP

I have a sql script that select the last three dates from current day in my base like below :
select distinct file_date
from my_database
where file_date > DATEADD(DAY, -3, CONVERT(date, SYSDATETIME()));
This is correct for me just in Wednesday, Thursday and Friday, BUT in Monday i wanna excluding the weekdays
For Monday for example, I wanna just the file_date for Friday and current Monday .and For Tuesday, I wanna just the file_date for Tuesday and Monday only.
How can I excluding the holidays and weekdays.
Thanks for Help.
No sample data and DB structure, also i asumed you have MYSQL DB so i will just give a hint how to do it in MYSQL
You can use WEEKDAY() as filter for the days of week.
For example this in normal query filter the results only for monday to friday:
SELECT *
FROM some_table
WHERE WEEKDAY(date_field) < 5
You can also do it in php. Increase your results to 5 rows (to include the possible weekends) and order the results by descending date.
//you have $results array with 5 elements
$lastThreeDays = [];
$i = 0;
foreach ($results as $res) {
$tStamp = strtotime($res['date_field']);
$weekDay = date('N',$tStamp);
if ($weekDay < 6 && $i < 3) {
$lastThreeDays[] = $res;
$i++;
}
}
No you have 3 records of the last 3 days excluding the weekdays.

PHP Count Between Date and Todays Date

In my dates database I have a table of dates that have two followups to be completed, one after 30 days, one after 60 days. I need to build a page that uses the MySQL query to pull all dates from the dates table that have a 30day value of No (which I can do). Now the tricky part is, I need it to only output the dates that meet that criteria, and are 30 days from the current date.
For example: August 4 & 6 have a 30day value of No, August 5 has a 30day value of Yes. Today's date is September 4. 30-days prior would be August 5.
I need the query to only display August 4 in this case, since it hasn't been 30 days since August 6 and August 5 has already been done.
I am unsure what kind of function to use to do this counting. I appreciate your help
EDIT:
Date - 30day Value
July 1 - Yes
July 5 - No
August 1 - No
August 5 - No
August 6 - Yes
Today's Date is September 2.
The table would display July 5 and August 1, as their 30day values are No, and they are more than 30 days from todays date.
You should use DATEDIFF function:
SELECT ....
FROM your_table
WHERE DATEDIFF(CURDATE(), event_date) = 30
Where event_date is example of your date column.
MySQL's DATEDIFF function allows you to subtract 2 dates in a query.
http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_datediff
DATEDIFF() returns expr1 − expr2 expressed as a value in days from one date to the other. expr1 and expr2 are date or date-and-time expressions. Only the date parts of the values are used in the calculation.
For example:
SELECT some_id, date_column
FROM date_table
WHERE DATEDIFF(CURDATE(), date_column) = 30
You could also select both 30 and 60 days like this and also have a cutoff date of 60 days so it's not searching the whole table:
SELECT some_id, date_column
FROM date_table
WHERE date_column>=DATE_SUB(CURDATE(), INTERVAL 60 DAY)
AND DATEDIFF(CURDATE(), date_column) IN (30, 60)
And since I'm making some assumptions with my understanding of what you're asking, you may also want to do this which will return the results as 'Yes' or 'No' in your result set:
SELECT some_id, date_column,
CASE DATEDIFF(CURDATE(), date_column)
WHEN 60 THEN 'Yes'
WHEN 30 THEN 'Yes'
ELSE 'No'
END CASE AS is_3060_day
FROM date_table
WHERE date_column>=DATE_SUB(CURDATE(), INTERVAL 60 DAY)
Alternatively if you want to accomplish this on the PHP side, you could use PHP's date_diff function:
http://php.net/manual/en/function.date-diff.php
function dateDifference($date_1 , $date_2 , $differenceFormat = '%a' )
{
$datetime1 = date_create($date_1);
$datetime2 = date_create($date_2);
$interval = date_diff($datetime1, $datetime2);
return $interval->format($differenceFormat);
}
$result = dateDifference($date1, $date2)
if ($result==30 || $result==60) {
// Do something
}
you can fetch both the dates and use the php function
$prevdate = date_create("2013-03-15");
$currdate = date_create("2013-12-12");
$diff = date_diff($prevdate,$currdate);
echo $diff->format("%R%a days");
Output
272 days

how to compare last week and last month date functions

$start = strtotime('this week');
$results =$wpdb->get_results("SELECT count( doctor_name ) AS totalleads FROM `wp-leads-count` WHERE doctor_name ='Sasanthi' and leads_date >='". $start."'");
this is my code to get last week leads count from table doctor name and where date with in this week (means today is thusday then start from previous week)
it not working??
and have do same for function like last month ??
in my db i use this leads_date field as timestamp
you can use the date_sub function from mysql
get all records from last week
SELECT count(doctor_name) AS totalleads FROM `wp-leads-count` WHERE doctor_name ='Sasanthi' and leads_date between date_sub(now(),INTERVAL 1 WEEK) and now()
get all records from last month
SELECT count(doctor_name) AS totalleads FROM `wp-leads-count` WHERE doctor_name ='Sasanthi' and leads_date between date_sub(now(),INTERVAL 1 MONTH) and now()
try
$daynumber = date('N', date('d'));// getting today day number
$prevweek = $daynumber+7; // starting from prev week
echo $prevdate = strtotime('-'.$prevweek.' days'); // prev week date
echo strtotime("-1 month"); // last month
For more :-
Getting last month's date in php
day of the week to day number (Monday = 1, Tuesday = 2)

Categories