Calculate 2 dates excluding weekends VB net - vb.net

I'm trying compute the dates of Due date into Date Returned. And if the date return pass the due date in one day. there will be a fine.
This is my code in computation
Dim st As Integer = MetroDateTime1.Value.Date.Subtract(Label9.Text).Days
If (Label6.Text) > (MetroDateTime1.Value.Date) Then _
MessageBox.Show("Date return must not below to date borrowed", _
"Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
MetroDateTime1.Focus()
ElseIf (st > 0) Then
MetroTextBox7.Text = (st * 5).ToString()
Else
MetroTextBox7.Text = 0
End If
'Metrotextbox7 is the textbox for fines. But, how to compute the dates excluding the weekends?

'get business Days
Public Shared Function GetBusinessDays(startDay As DateTime, endDay As DateTime) As Integer
Dim today = Date.Today
Dim weekend = {DayOfWeek.Saturday, DayOfWeek.Sunday}
Dim businessDays =
From d In Enumerable.Range(0, (endDay.Date - startDay.Date).Days + 1)
Select day = today.AddDays(d)
Where Not weekend.Contains(day.DayOfWeek)
Return businessDays.Count()
End Function
already answered question

Related

VB.Net find last day of month with date format

I am trying to find the last day of the month and compare it to today's date
I do NOT want the integer number I would like the result in this format "MM-dd-yyyy"
Date Picker will not work for this project
Here is the code I using but the process seems overly complicated concocting strings
Side note when today is after the 4th Tue I write True and the Last Day of the month to a DB
when today is after the last day of the month and the bool is now True I write the new last day of the new month and false to the DB
Function FourthTueOfMonth(dt As Date) As Date
Dim currDate = New Date(dt.Year, dt.Month, 1)
Dim nTuesday = 0
While nTuesday < 4
If currDate.DayOfWeek = DayOfWeek.Tuesday Then
nTuesday += 1
End If
currDate = currDate.AddDays(1)
End While
Return New Date(dt.Year, dt.Month, currDate.Day - 1)
End Function
Private Sub btnFindDate_Click(sender As Object, e As EventArgs) Handles btnFindDate.Click
Dim tORf As Boolean = False
Dim dateToday = Date.Today
Dim dateFourthTue = (FourthTueOfMonth(Date.Today))
tbFourthTue.Text = dateFourthTue.ToString("MMM-dd-yyyy")
tbThree.Text = dateFourthTue.ToString("yyyy-MM-dd")
tbEndOFMonth.Text = Date.DaysInMonth(Date.Now.Year, Date.Now.AddMonths(0).Month).ToString
Dim dToday As Date
dToday = Date.Parse("10-01-2021")
Dim dtY = dateToday.ToString("yyyy")
Dim dtM = dateToday.ToString("MM")
Dim eom As String = Date.DaysInMonth(Date.Now.Year, Date.Now.AddMonths(0).Month).ToString
Dim dtALL As String
dtALL = dtM & "-" & eom & "-" + dtY
Dim testD As Date
testD = Date.Parse(dtALL)
If tORf = False And dToday > dateFourthTue Then
MessageBox.Show("Today > Fourth Tue")
'tORf = True'Write True
'tbMessage.Text = tORf.ToString
End If
If tORf = True And dToday > testD Then
MessageBox.Show("Today > End Of Last Month")
'tORf = False write False
'tbMessage.Text = tORf.ToString
End If
End Sub
The solution provided by #Albert D. Kallal is great for Visual Basic since DateSerial is in the Visual Basic namespace in the DateAndTime class. Here is a solution that should work in both vb and C#.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dtToday As Date = Date.Today
Dim dtEndOfMonth = New Date(dtToday.Year, dtToday.Month + 1, 1).AddDays(-1)
Debug.Print(dtToday.ToString)
Debug.Print(dtEndOfMonth.ToString("MM-dd-yyyy"))
End Sub
A few things:
You want to use today - not "now()" as that includes a time portion. While a date type only has date, you should consider if you have datetime, and either way, no need to introduce and use a value that includes both date and time such as now does.
I reocmmend this code:
Dim dtToday As Date = Date.Today
Dim dtEndOfMonth As Date = DateSerial(dtToday.Year, dtToday.Month + 1, 0)
Debug.Print(dtToday)
Debug.Print(dtEndOfMonth)
Output:
Today happens to be the 1st, but any date would work. This includes end of year, and even leap years.
2021-10-01
2021-10-31
So, this is a long time old trick - goes back to old VB6, and even old VBA code from 20 years ago.
So, we use date serial to produce a date, but if you use 0 for the day, then you get the previous day, and thus gets you the last day of the current month.
So we toss in year, month + 1, and 0 for the date - that results in the last day of the current month.
I hate to admit I might have gave up the search too quick
found the answer here
Answer Here
Here is the code
Dim dateToday = Date.Now.AddMonths(0)
Dim dateEndOfMonth = New Date(dateToday.Year, dateToday.Month, DateTime.DaysInMonth(dateToday.Year, dateToday.Month))
tbMsg.Text = dateEndOfMonth.ToString("MM-dd-yyyy")
Code seems to be working ?
I have seen suggestions to use this format for comparing dates
TEST DATES use this format yyyyMMdd Please comment if you can add to the answer

Get same nth day of the month in x number of months

I am needing some help converting a function from access vba to vb.net.
The script generates a new date, based on the date entered, and the number of months to be added.
“If today is the second Tuesday in March, what will be the second Tuesday in 4 months?”
Public Function NdNwk(dType As String, _
dtSpan As Integer, sDate As Date) As Variant
' This Function RETURNS the DAY of WHICH WEEK
' (e.g. Second Tuesday of the Month).
' FUNCTIONS to be passed to Variables:
' gtDoW: Day of the WEEK of the START DATE.
' (1 for Sunday, 2 for Monday, etc.)
' gtWoM: WEEK of the MONTH of the START DATE.
' (1 for First, 2 for Second, etc.)
' gtDSTdt: Desired DATE
' (generated by the [DateAdd] Function).
' CALL EXAMPLE: If TODAY is Tuesday, March 10, 2020,
‘ (second Tuesday of March), then using
' NdNwk(m, 2, #5/21/2020#)
' Would generate the DATE 5/12/2020,
' As the SECOND TUESDAY of MAY.
Dim gtDSTdt As Date, gtWoM As Integer, gtDoW As Integer
Dim iLoop As Integer, iPick As Integer, dstDTdom As Date
gtDoW = Weekday(sDate)
gtWoM = (Int((Day(sDate) - 1) / 7) + 1)
gtDSTdt = DateAdd(dType, dtSpan, sDate)
For iLoop = 1 To Day(DateSerial(Year(gtDSTdt), _
Month(gtDSTdt) + 1, 0))
dstDTdom = DateSerial(Year(gtDSTdt), _
Month(gtDSTdt), iLoop)
If Weekday(dstDTdom, 1) = gtDoW Then
iPick = iPick + 1
If iPick = gtWoM Then
NdNwk = dstDTdom
Exit Function
End If
End If
Next
End Function
Any and all help is appreciated here.
I used several of the properties and methods of the .net DateTime structure. https://learn.microsoft.com/en-us/dotnet/api/system.datetime?view=netcore-3.1
The arithmetic in the Function used the Mod operator which returns the remainder of the division. The integer division (the formard slash \) returns the integer portion of the division.
The only other thing that might be unfamiliar is the interpolated string, a string starting with $"". This allows you to directly embed variables in the string surround by { }.
Private Function NdNwk(InputDate As Date, MonthsAhead As Integer) As String
Dim newDate As Date
Dim DofWeek = InputDate.DayOfWeek
Dim Day = InputDate.Day
Dim OfInputMonth As Integer
If Day Mod 7 = 0 Then
OfInputMonth = Day \ 7
Else
OfInputMonth = (Day \ 7) + 1
End If
Dim TempDate = InputDate.AddMonths(MonthsAhead)
Dim NewMonth = TempDate.Month
Dim NewYear = TempDate.Year
Dim FirstWeek As Date
Dim NewDay As Integer
For d = 1 To 7
FirstWeek = New Date(TempDate.Year, TempDate.Month, d)
If FirstWeek.DayOfWeek = DofWeek Then
NewDay = d
Exit For
End If
Next
Dim DaysToAdd = (OfInputMonth - 1) * 7
newDate = New Date(NewYear, NewMonth, NewDay).AddDays(DaysToAdd)
Dim NewDateString = $"{newDate.ToString("MM/dd/yyyy")} is the {GetOrdinalString(OfInputMonth)} {DofWeek} of {TempDate.ToString("MMMM")}, {TempDate.Year}"
Return NewDateString
End Function
Private Function GetOrdinalString(input As Integer) As String
Dim output As String
Select Case input
Case 1
output = "1St"
Case 2
output = "2nd"
Case 3
output = "3rd"
Case 4
output = "4th"
Case 5
output = "5th"
Case Else
output = ""
End Select
Return output
End Function
Usage...
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim InputDate As Date
Dim MonthsToAdd As Integer
If Not Date.TryParse(TextBox1.Text, InputDate) Then
MessageBox.Show("Please enter a valid date in Date")
Return
End If
If Not Integer.TryParse(TextBox2.Text, MonthsToAdd) Then
MessageBox.Show("Please enter a valid number in Months To Add")
Return
End If
Dim d = NdNwk(InputDate, MonthsToAdd)
MessageBox.Show(d)
End Sub
First of all, thanks for all the feedback.
The solution that I was able to parse together is as follows:
A text box to show the number of months.
A text box to show the new date.
A button click action to run the following code:
Private Sub BtnMonth_Click(sender As Object, e As EventArgs) Handles BtnMonth.Click
Dim WrkDt As Date = Now
Dim QtyMnths As Integer = CType(TxtMntCount.Text, Int32)
Dim newFoM = New Date(WrkDt.Year, WrkDt.Month, 1).AddMonths(QtyMnths)
Dim DoWDt As Integer = WrkDt.DayOfWeek
Dim newMntdate = newFoM.AddDays(Enumerable.Range(0,
Date.DaysInMonth(newFoM.Year, newFoM.Month) - 1).Where(Function(i) newFoM.AddDays(i).DayOfWeek = DoWDt).Skip(1).First())
TxtNewDate.Text = Format(newMntdate, "MMMM dd, yyyy (ddd)")
End Sub
This works perfectly fine for me!
Mary's solution looks great, and I will give it a shot in the future when I need a modular input.
Thanks again for all the help!
I tested your solution, and it doesn’t produce the described results.
See test and correct solution at: https://dotnetfiddle.net/v5wGng
A couple of things from your original problem, you should prefer calculation to loops wherever possible, and you should use the required types wherever possible. If you have date in one format (string) and need it in another for your calculations, you should do the conversion and then call a function that does your calculations where all of the parameters are of the correct type.
Public Function GetSameWeekAndWeekDay(dt as date, months as integer) as Date
Dim newMonth =(new date(dt.year, dt.month, 1)).AddMonths(Months)
Dim week = getweek(dt)
Dim sameWeekDay = GetNthDayOfWeek(newMonth, week, dt.DayOfWeek)
Return SameWeekday
End Function
Public Function GetWeek(dt as date) as integer
Return(dt.day - 1) \ 7
End Function
Public Function GetNthDayOfWeek(dt as date, week as integer, weekDay as System.DayofWeek) as Date
Dim first = new Date(dt.year, dt.month, 1)
Dim baseDate = first.AddDays(-(first.DayOfWeek - system.dayofweek.Sunday))
Dim newDate = baseDate.AddDays((week * 7) + weekday)
If(newdate.DayOfWeek < first.DayOfWeek) then
newDate = newDate.AddDays(7)
End If
Return newdate
End Function

How to calculate the second Tuesday of said month of said year in Visual Basic [duplicate]

I was looking for a function in VB.net that returns the date of the specified weekday of a given week in a month. Something similar to Outlook appointments.
for example:
First Monday of the month,
Second Thursday of the month or
Last Saturday of the month
I searched but couldn't find anything versatile enough to all the options. So I created my own and would like to share it.
Here is what I came up with:
Public Function GetDate()
Dim dt As Date = Today
Dim FirstWeek As Integer = 1
Dim SecondWeek As Integer = 2
Dim ThirdWeek As Integer = 3
Dim FourthWeek As Integer = 4
Dim LastWeek As Integer = 5
MsgBox(GetNthDayOfNthWeek(dt, DayOfWeek.Monday, LastWeek).ToString)
End Function
Public Function GetNthDayOfNthWeek(ByVal dt As Date, ByVal DayofWeek As Integer, ByVal WhichWeek As Integer) As Date
'specify which day of which week of a month and this function will get the date
'this function uses the month and year of the date provided
'get first day of the given date
Dim dtFirst As Date = DateSerial(dt.Year, dt.Month, 1)
'get first DayOfWeek of the month
Dim dtRet As Date = dtFirst.AddDays(6 - dtFirst.AddDays(-(DayofWeek + 1)).DayOfWeek)
'get which week
dtRet = dtRet.AddDays((WhichWeek - 1) * 7)
'if day is past end of month then adjust backwards a week
If dtRet >= dtFirst.AddMonths(1) Then
dtRet = dtRet.AddDays(-7)
End If
'return
Return dtRet
End Function
Enjoy!
Public Function GetLastDayOfMonth(ByVal iMonth As Integer, ByVal iYear As Integer) As Integer
Dim LastDate = DateSerial(iYear, iMonth + 1, 0)
GetLastDayOfMonth = LastDate.Day
Return GetLastDayOfMonth
End Function
Private Function GetWeekNumberOfMonth(ByVal Dt As Date) As Integer
Dim LastDate = New DateTime(Dt.Year, Dt.Month, GetLastDayOfMonth(Dt.Month, Dt.Year), Dt.Hour, Dt.Minute, Dt.Second, Dt.Kind)
Dim weekNumber As Integer = Math.Ceiling(Dt.Day / 7)
If weekNumber = 4 Then
Dim dateDiff = CInt((LastDate - Dt).TotalDays)
If dateDiff < 7 Then weekNumber = 5
End If
Return weekNumber
End Function

vba type mismatch on my script

So, I'm getting a type mismatch in the VBA script of a Word document, however there isn't any line signaled on the editor... Can any of you give me an hint of what it might be?
Private Sub bt_run_Click()
'set months array
Dim months As Variable
months = Array("Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro")
With ThisDocument.Tables(0)
Do While .Rows.Count > 2
.Rows(2).Delete
Loop
'Ask for year
Dim req As String
Dim yr As Integer
req = InputBox("Insere ano.")
If IsNumeric(req) Then
yr = CInt(req)
Else
MsgBox ("Erro")
Return
End If
'get previous year last week
'TODO
'Now generate current year months
For i = 1 To 12
'get number of mondays on the month (how many weeks belong here)
Dim mondays As Integer
mondays = MondaysOnMonth(i, yr)
'now generate a line for each monday
For k = 1 To mondays
.Rows.Add
Next k
Next i
'get next year first week
'TODO
End With
End Sub
Function MondaysOnMonth(ByVal month As Integer, ByVal year As Integer) As Integer
Dim mondays As Integer
mondays = 0
Dim d As Date
Dim dtStr As String
dtStr = "1/" & month & "/" & year
d = DateValue(dtStr)
Dim days As Integer
days = dhDaysInMonth(d)
For i = 1 To days
dtStr = i & "/" & month & "/" & year
d = DateValue(dtStr)
Dim w As Integer
w = Weekday(d, vbMonday)
If w = 0 Then
mondays = mondays + 1
End If
Next i
MondaysOnMonth = mondays
End Function
Function dhDaysInMonth(Optional ByVal dtmDate As Date = 0) As Integer
' Return the number of days in the specified month.
If dtmDate = 0 Then
' Did the caller pass in a date? If not, use
' the current date.
dtmDate = Date
End If
dhDaysInMonth = DateSerial(year(dtmDate), _
month(dtmDate) + 1, 1) - _
DateSerial(year(dtmDate), month(dtmDate), 1)
End Function
This pretty much generates how many lines as there're mondays in the entire year in the only table of the document.
I'm not really experienced in all this thing of Visual Basic for Applications, but I'm assuming it's some type casting that the compiler can't execute, however, I can't really see what it might be (and the compiler isn't giving me the necessary help), so what might it be?
In my (limited) experience, arrays are setup a little differently in VBA:
'set months array
Dim months(11) As String
months(0) = "Janeiro"
months(1) = "Fevereiro"
months(2) = "Março"
months(3) = "Abril"
months(4) = "Maio"
months(5) = "Junho"
months(6) = "Julho"
months(7) = "Agosto"
months(8) = "Setembro"
months(9) = "Outubro"
months(10) = "Novembro"
months(11) = "Dezembro"
Also, I could not address table 0, so changed it to table 1 and the code seemed to execute.
With ThisDocument.Tables(1)
Hope this helps!
Array Function
Returns a Variant containing an array!!!
Dim months As Variant
You were so close.
In your original code, you should be able to change Variable to Variant and the initialization will work as you expected.
Here I've copy/pasted your array initialization, swapped in Variant, and written a loop that confirms the array was properly initialized by printing the values to the Immediate Window (press Ctrl+G to view if it is not already visible):
Sub TestMonthArrayInitialization()
Dim months As Variant
months = Array("Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro")
Dim i As Integer
For i = 0 To 11
Debug.Print months(i)
Next i
End Sub

How do I get first, second or last Tuesday (or any day of the week) of a given month

I was looking for a function in VB.net that returns the date of the specified weekday of a given week in a month. Something similar to Outlook appointments.
for example:
First Monday of the month,
Second Thursday of the month or
Last Saturday of the month
I searched but couldn't find anything versatile enough to all the options. So I created my own and would like to share it.
Here is what I came up with:
Public Function GetDate()
Dim dt As Date = Today
Dim FirstWeek As Integer = 1
Dim SecondWeek As Integer = 2
Dim ThirdWeek As Integer = 3
Dim FourthWeek As Integer = 4
Dim LastWeek As Integer = 5
MsgBox(GetNthDayOfNthWeek(dt, DayOfWeek.Monday, LastWeek).ToString)
End Function
Public Function GetNthDayOfNthWeek(ByVal dt As Date, ByVal DayofWeek As Integer, ByVal WhichWeek As Integer) As Date
'specify which day of which week of a month and this function will get the date
'this function uses the month and year of the date provided
'get first day of the given date
Dim dtFirst As Date = DateSerial(dt.Year, dt.Month, 1)
'get first DayOfWeek of the month
Dim dtRet As Date = dtFirst.AddDays(6 - dtFirst.AddDays(-(DayofWeek + 1)).DayOfWeek)
'get which week
dtRet = dtRet.AddDays((WhichWeek - 1) * 7)
'if day is past end of month then adjust backwards a week
If dtRet >= dtFirst.AddMonths(1) Then
dtRet = dtRet.AddDays(-7)
End If
'return
Return dtRet
End Function
Enjoy!
Public Function GetLastDayOfMonth(ByVal iMonth As Integer, ByVal iYear As Integer) As Integer
Dim LastDate = DateSerial(iYear, iMonth + 1, 0)
GetLastDayOfMonth = LastDate.Day
Return GetLastDayOfMonth
End Function
Private Function GetWeekNumberOfMonth(ByVal Dt As Date) As Integer
Dim LastDate = New DateTime(Dt.Year, Dt.Month, GetLastDayOfMonth(Dt.Month, Dt.Year), Dt.Hour, Dt.Minute, Dt.Second, Dt.Kind)
Dim weekNumber As Integer = Math.Ceiling(Dt.Day / 7)
If weekNumber = 4 Then
Dim dateDiff = CInt((LastDate - Dt).TotalDays)
If dateDiff < 7 Then weekNumber = 5
End If
Return weekNumber
End Function