calculate how many weekend days inside date? - ms-access

I need to calculate how many weekend days inside 2 dates? what I mean is that I have 2 dates and want to know the count of Saturdays & Sundays between these dates.
I have the 2 dates on each record (from date - to date) and want to query the count of weekends.

The following VBA function will allow you to run Access queries of the form
SELECT CountWeekendDays([from date], [to date]) AS WeekendDays FROM YourTable
Just create a new Module in Access and paste the following code into it:
Public Function CountWeekendDays(Date1 As Date, Date2 As Date) As Long
Dim StartDate As Date, EndDate As Date, _
WeekendDays As Long, i As Long
If Date1 > Date2 Then
StartDate = Date2
EndDate = Date1
Else
StartDate = Date1
EndDate = Date2
End If
WeekendDays = 0
For i = 0 To DateDiff("d", StartDate, EndDate)
Select Case Weekday(DateAdd("d", i, StartDate))
Case 1, 7
WeekendDays = WeekendDays + 1
End Select
Next
CountWeekendDays = WeekendDays
End Function

Related

Calculate no. of working hours between two given dates(exclude the weekends)

I want to calculate no. of working hours between two given dates(excluding weekends) and it should be within business hours(8:00 AM - 5:00 PM).
I have 3 tables:
table 1 contains open dates and closed dates for different jobs.
table 2 contains the working hours(2 columns start time(8:00 AM) and end time(5:00 PM)).
Table 3 contains date and the day on that date.
For eg.
open date - 2015-10-16 06:00:00 & closed date - 2015-10-19
15:00:00 working_hours_start - 8:00 AM & working_hours_end - 5:00 PM
Answer - 16 hrs
I had this requirement and have written complete function that can calculate while avoiding hours of weekend and holidays for a given country (using a separate table). I have put the whole function and details on my blog (http://mgw.dumatics.com/mysql-function-to-calculate-elapsed-working-time/) along with explanation and flowchart and creation of holiday table etc...
Example of problem resolved:
Let's say an incident was logged on "Friday 10th June 2016 at 12:00" for a site in the "UK" which opens between 09:00 to 16:00. This incident was then closed on "Tuesday 14th June 2016 at 14:00".
For the above incident function should calculate the age as 960 minutes = 16 hours = [4 hours on Friday (12:00 to 16:00) + 7 hours on Monday (09:00 to 16:00) + 5 hours on Tuesday (09:00 to 14:00)]
CREATE FUNCTION WorkTime
(
reported_datetime DATETIME,
closed_datetime DATETIME
)
RETURNS DOUBLE
BEGIN
DECLARE FirstDay, LastDay, CurrentDate, LastDate DATE;
DECLARE StartTime, FinishTime, WorkStart, WorkFinish, DailyWorkTime TIME;
DECLARE Temp DOUBLE;
SET Temp = 0;
SET FirstDay = DATE(reported_datetime);
SET LastDay = DATE(closed_datetime);
SET StartTime = TIME(reported_datetime);
SET FinishTime = TIME(closed_datetime);
SET WorkStart = '08:00:00';
SET WorkFinish = '17:00:00';
SET DailyWorkTime = TIMEDIFF(WorkFinish,WorkStart);
IF (StartTime < WorkStart)
THEN
SET StartTime = WorkStart;
END IF;
IF (FinishTime > WorkFinish)
THEN
SET FinishTime = WorkFinish;
END IF;
SET CurrentDate = FirstDay;
SET LastDate = LastDay;
WHILE(CurrentDate <= LastDate)
DO
IF (DAYOFWEEK(CurrentDate)!=1 AND DAYOFWEEK(CurrentDate)!=7)
THEN
IF (CurrentDate != FirstDay) AND (CurrentDate != LastDay)
THEN
SET Temp = Temp + TIME_TO_SEC(DailyWorkTime)/3600;
ELSEIF (CurrentDate = FirstDay) AND (CurrentDate != LastDay)
THEN
SET Temp = Temp + GREATEST(TIME_TO_SEC(TIMEDIFF(WorkFinish,StartTime)),0)/3600;
ELSEIF (CurrentDate != FirstDay) AND (CurrentDate = LastDay)
THEN
SET Temp = Temp + GREATEST(TIME_TO_SEC(TIMEDIFF(FinishTime,WorkStart)),0)/3600;
ELSEIF (CurrentDate = FirstDay) AND (CurrentDate = LastDay)
THEN
SET Temp = TIME_TO_SEC(TIMEDIFF(FinishTime,StartTime))/3600;
END IF;
END IF;
SET CurrentDate = DATE_ADD(CurrentDate, INTERVAL 1 DAY);
END WHILE;
IF Temp < 0
THEN
SET Temp = 0;
END IF;
RETURN Temp;
END$$;
Try mysql timediff
time_to_sec(timediff('2015-10-16 06:00:00', '2015-10-19 15:00:00 ' )) / 3600
Day not saturday and sunday
where WEEKDAY(date) !=5 and WEEKDAY(date) !=6
and try query like this demo
select *,time_to_sec(timediff(date_note1, date_note2)) / 3600 from (SELECT CASE
WHEN DATE_FORMAT(date,'%H:%i:%s') < '8:00:00' THEN CONCAT(date, ' 8:00:00')
ELSE date
END AS date_note1 ,
CASE
WHEN DATE_FORMAT(date2,'%H:%i:%s') > '17:00:00' THEN CONCAT(date2, ' 17:00:00')
ELSE date2
END AS date_note2
FROM `test` where WEEKDAY(date) !=5 and WEEKDAY(date) !=6) as tbl

Access Query. If records Due Date = Last Week Insert Yes in Cell

Good morning All,
I am working on the following however, I can't figure it out for the life of me. I have table that contains a bunch of due dates. What I am trying to do is add a query that adds another field and inserts a yes if the date equals a day in last week. Honestly I need it to insert yes as long as it does not = this week.
I've tried using:
Urgent: IIf([Due Date]=[Due Date]
Between
DateAdd("d",1-Weekday(Date()) 7, Date()) And
DateAdd("d",1-Weekday(Date())-1, Date()),"Yes","")
with no luck. What am I missing here?!
Thanks all. Cheers.
Here's how to return Urgent if 'not this week' means previous Saturday and before. Not sure how you would do it without code.
Helper Function to get the first day of this week based on current date. Paste it into a new or existing global module.
Function FirstDateOfTheWeek() As Date
Dim dt As Date
If Weekday(Date) = vbSaturday Then
FirstDateOfTheWeek = DateAdd("y", -6, Date) 'today is Saturday? then return previous Sunday
ElseIf Weekday(Date) = vbSunday Then
FirstDateOfTheWeek = Date 'today is Sunday? then return Sunday because its the first day of the week
Else 'weekday, so just go backwards until we hit previous sunday's date
dt = Date
While Weekday(dt) <> vbSunday
dt = DateAdd("y", -1, dt)
Wend
FirstDateOfTheWeek = dt
End If
End Function
An IsUrgent function to be called from query. Paste it into a new or existing global module.
Function IsUrgent(dt As Variant) As String
If IsNull(dt) Then 'if null date is passed then return blank string; Variant chosen instead of date for this case; change it to N/A if you want?
IsUrgent = ""
Exit Function
End If
If dt < FirstDateOfTheWeek Then
IsUrgent = "Yes"
Else
IsUrgent = ""
End If
End Function
The Query Column calling IsUrgent() function:
IsUrgent: IsUrgent([Due Date])

capture dates by quarters in access

To make my life much easier working with my data I set 3 columns of same date content. The first displays in the format mm/dd/yyyy, second in the format of yyyy-mm and the third in the format yyyy-q.
I did it purposely due to my reports. Sometimes I need to create monthly, quarterly, yearly etc. Usually I work with a form where I invite the user select start and end date and by a click of a button run a report. This report extracts a query where I specify on the date section to pull all information between start and end date. This time I want to do the same procedure but instead of start and end date - I want the user to select which quarter he wants so that the query will pull all information regarding this quarter. What do I specify in the criteria to archive this?
Filter on
DatePart("q", [YourDateField])
or
Format([YourDateField], "yyyyq")
To obtain the first and last date of a quarter, given the year and the quarter, you can use these expressions:
DateQuarterFirst = DateSerial(Y, 1 + 3 * (Q - 1), 1)
DateQuarterLast = DateSerial(Y, 1 + 3 * Q, 0)
If you have a date of the quarter, you can these functions to obtain the first and last date of the quarter of that date:
Public Function DateThisQuarterFirst( _
Optional ByVal datDateThisQuarter As Date) As Date
Const cintQuarterMonthCount As Integer = 3
Dim intThisMonth As Integer
If datDateThisQuarter = 0 Then
datDateThisQuarter = Date
End If
intThisMonth = (DatePart("q", datDateThisQuarter) - 1) * cintQuarterMonthCount
DateThisQuarterFirst = DateSerial(Year(datDateThisQuarter), intThisMonth + 1, 1)
End Function
Public Function DateThisQuarterLast( _
Optional ByVal datDateThisQuarter As Date) As Date
Const cintQuarterMonthCount As Integer = 3
Dim intThisMonth As Integer
If datDateThisQuarter = 0 Then
datDateThisQuarter = Date
End If
intThisMonth = DatePart("q", datDateThisQuarter) * cintQuarterMonthCount
DateThisQuarterLast = DateSerial(Year(datDateThisQuarter), intThisMonth + 1, 0)
End Function

How to get start and end of previous month in VB

Im trying to create some VB code that will get the start and end of the previous month.
Im able to the current month which is just:
Month(DateValue(Now))
which would return 3. From there I can take away 1 to give me 2 meaning February. This is fine but what about when I Im in January and I repeat this and it gives me zero - my code will fail. Any one know how to get the previous months start and end day then?
Thanks
The first day of the previous month is always 1, to get the last day of the previous month, use 0 with DateSerial:
''Today is 20/03/2013 in dd/mm/yyyy
DateSerial(Year(Date),Month(Date),0) = 28/02/2013
DateSerial(Year(Date),1,0) = 31/12/2012
You can get the first day from the above like so:
LastDay = DateSerial(Year(Date),Month(Date),0)
FirstDay = LastDay-Day(LastDay)+1
See also: How to caculate last business day of month in VBScript
I have similar formula for the First and Last Day
The First Day of the month
FirstDay = DateSerial(Year(Date),Month(Date),1)
The zero Day of the next month is the Last Day of the month
LastDay = DateSerial(Year(Date),Month(Date)+ 1,0)
firstDay = DateSerial(Year(DateAdd("m", -1, Now)), Month(DateAdd("m", -1, Now)), 1)
lastDay = DateAdd("d", -1, DateSerial(Year(Now), Month(Now), 1))
This is another way to do it, but I think Remou's version looks cleaner.
Try this
First_Day_Of_Previous_Month = New Date(Today.Year, Today.Month, 1).AddMonths(-1)
Last_Day_Of_Previous_Month = New Date(Today.Year, Today.Month, 1).AddDays(-1)
This works reliably for me in my main sub.
Dim defDate1 As Date, defDate2 As Date
'** Set default date range to previous month
defDate1 = CDate(Month(Now) & "/1/" & Year(Now))
defDate1 = DateAdd("m", -1, defDate1)
defDate2 = DateAdd("d", -1, DateAdd("m", 1, defDate1))
Try this to get the month in number form:
Month(DateAdd("m", -3, Now))
It will give you 12 for December.
So in your case you would use Month(DateAdd("m", -1, Now)) to just subract one month.
Just to add something to what #Fionnuala Said, The below functions can be used. These even work for leap years.
'If you pass #2016/20/01# you get #2016/31/01#
Public Function GetLastDate(tempDate As Date) As Date
GetLastDate = DateSerial(Year(tempDate), Month(tempDate) + 1, 0)
End Function
'If you pass #2016/20/01# you get 31
Public Function GetLastDay(tempDate As Date) As Integer
GetLastDay = Day(DateSerial(Year(tempDate), Month(tempDate) + 1, 0))
End Function
Public Shared Function GetFOMPrev(ByVal tdate As Date) As Date
Return tdate.AddDays(-(tdate.Day - 1))
End Function
Public Shared Function GetEOMPrev(ByVal tdate As Date) As Date
Return tdate.AddDays(-tdate.Day)
End Function
Usage:
'Get End of Month of Previous Month - Pass today's date
EOM = GetEOMPrev(Date.Today)
'Get First of Month of Previous Month - Pass date just calculated
FOM = GetFOMPrev(EOM)

Find number of weekdays/weekends in a given date range

I'm trying to find some VBA code to determine the number of week days and weekend days in a given date range using Access VBA.
For example:
Begin Date - 1/1/2012
End Date - 1/31/2012
Result should be:
Week days - 22
Weekend days - 9
Can anyone help out with this?
These two functions will calculate the number of weekdays and weekend days:
Function NumWeekendDays(dBegin As Date, dEnd As Date) As Long
Dim iPartial As Integer
Dim lBeginDay As Long
Dim lNumWeekendDays As Long
iPartial = DateDiff("d", dBegin, dEnd + 1) Mod 7
lBeginDay = 6 - DatePart("w", dBegin, vbMonday)
lNumWeekendDays = (DateDiff("d", dBegin, dEnd + 1) \ 7) * 2
If iPartial > 0 And lBeginDay - iPartial < 0 Then
If lBeginDay = -1 Then
lNumWeekendDays = lNumWeekendDays + 1
ElseIf iPartial - lBeginDay = 1 Then
lNumWeekendDays = lNumWeekendDays + 1
Else
lNumWeekendDays = lNumWeekendDays + 2
End If
End If
NumWeekendDays = lNumWeekendDays
End Function
Function NumWeekDays(dBegin As Date, dEnd As Date) As Long
NumWeekDays = DateDiff("d", dBegin, dEnd + 1) - NumWeekendDays(dBegin, dEnd)
End Function
Note: I found it simplest to calculate the partial-week weekend days by calculating the lBeginDay variable so that if the start date was Monday, lBeginDay == 5... if the start date was Friday, lBeginDay == 1, etc. Other variations should also work.