VB.net loop through if-then statements? - vb.net

I have written a private sub which gets the current time and works out which time bracket (from a timespan array) the current time falls into. Given that there are ten time brackets I'm testing for, the code is repetitive and only the integer index of the array and the result integer change between each if statement.
If DateTime.Now.TimeOfDay >= tmeToday(0) AndAlso DateTime.Now.TimeOfDay <= tmeToday(1) Then
intPeriodFrid = 0 'ext morning; 8am - 9am
intNextBell = 1
ElseIf DateTime.Now.TimeOfDay >= tmeToday(1) AndAlso DateTime.Now.TimeOfDay <= tmeToday(2) Then
intPeriodFrid = 1 'morning break; 9am - 9:05am
intNextBell = 2
... ridiculous amounts of repetition later
ElseIf DateTime.Now.TimeOfDay >= tmeToday(10) AndAlso DateTime.Now.TimeOfDay <= tmeToday(11) Then
intPeriodFrid = 10 'ext afternoon; 3:10pm - 4:10pm
intNextBell = 11
End If
Then it hit me I could probably do it like this:
For value As Integer = 0 To 10
If DateTime.Now.TimeOfDay >= tmeToday(value) AndAlso DateTime.Now.TimeOfDay <= tmeToday(value + 1) Then
intPeriodFrid = value
intNextBell = (value + 1)
Exit For
End If
Next
This would/will be my first ever use of a loop (I'm ten weeks into a VB.NET based course), so I lack confidence in this as a solution, will it work? Any weaknesses/problems I need to look out for if I implement this?

Related

Problems in the While Loop: Adding a thing to the list only once

I want to make restaurant bookings. As long as the guest is in the hotel, the guest should eat in the morning, at noon and in the evening. I have a booking_of_restaurant class for this. In the form in which the hotel reservation is made, the restaurant is then also booked for the period in question.
My code still books way too much – it would be enough to have one breakfast, one lunch and one dinner 😅. I can't think of how to solve it.
Both start and end dates are given in text boxes with the time. The time is therefore not the default 12 A.M.
Restaurant_reservations As New List(Of booking_of_restaurant)
Private Sub Button_addGuest_Click(sender As Object, e As EventArgs) Handles Button_addGuest.Click
Dim currentDate As Date = Start_date
While currentDate < End_date
If currentDate.Hour >= 7 AndAlso currentDate.Hour < 11 Then
Restaurant_reservations.Add(New booking_of_restaurant(currentDate,
booking_of_restaurant.kind_of_meals.breakfast,
characteristic))
ElseIf currentDate.Hour > 11 AndAlso currentDate.Hour < 14 Then
Restaurant_reservations.Add(New booking_of_restaurant(currentDate,
booking_of_restaurant.kind_of_meals.lunch,
characteristic))
ElseIf currentDate.Hour >= 18 AndAlso currentDate.Hour < 22 Then
Restaurant_reservations.Add(New booking_of_restaurant(currentDate,
booking_of_restaurant.kind_of_meals.dinner,
characteristic))
End If
currentDate = currentDate.AddHours(1)
End While
End Sub
I tried this, but the error is
"booking_of_restaurant.kind_of_meals" is an enumeration type and cannot be used as an expression.
If Not Restaurant_reservations.Last().kind_of_meals = booking_of_restaurant.kind_of_meals.breakfast Then
End If
You are stepping in steps of 1 hour, so the loop is entering for instance the first block ten times (at 1:00, 2:00, 3:00, ...). So probably the easiest would be, stepping to the upper limit of the range, once a booking is made
Private Sub Button_addGuest_Click(sender As Object, e As EventArgs) Handles Button_addGuest.Click
Dim currentDate As Date = Start_date
Dim addHours as Integer = 1
While currentDate < End_date
If currentDate.Hour > 0 AndAlso currentDate.Hour < 11 Then
Restaurant_reservations.Add(New booking_of_restaurant(currentDate,
booking_of_restaurant.kind_of_meals.breakfast,
characteristic))
addHours = 11 - currentDate.Hour
ElseIf currentDate.Hour > 11 AndAlso currentDate.Hour < 14 Then
Restaurant_reservations.Add(New booking_of_restaurant(currentDate,
booking_of_restaurant.kind_of_meals.lunch,
characteristic))
addHours = 14 - currentDate.Hour
ElseIf currentDate.Hour >= 18 AndAlso currentDate.Hour < 22 Then
Restaurant_reservations.Add(New booking_of_restaurant(currentDate,
booking_of_restaurant.kind_of_meals.dinner,
characteristic))
addHours = 22 - currentDate.Hour
End If
currentDate = currentDate.AddHours(addHours)
End While
End Sub

Exclude weekends in delivery date

I have a code that gets an ETA (estimated time of arrival) but I want it to exclude weekends. I also have it to change the ETA if its past 2:30PM.
Code:
Dim ETA1 As Date = Date.Today.AddDays(1)
Dim ETA2 As Date = Date.Today.AddDays(2)
Dim ETA3 As Date = Date.Today.AddDays(3)
Dim day As String = Format(Today, "dddd")
Dim time As Date
Dim CurrHour As Integer
Dim CurrMinute As Integer
time = DateTime.Now
CurrHour = time.Hour
CurrMinute = time.Minute
If StoreBox.Text Like "25*" Then
MicroLabel.Visible = True
If CurrHour >= 2 AndAlso CurrMinute >= 30 Then
ETABox.Text = ETA2
Else
ETABox.Text = ETA1
End If
Else
MicroLabel.Visible = False
If CurrHour >= 2 AndAlso CurrMinute >= 30 Then
ETABox.Text = ETA2
Else
ETABox.Text = ETA1
End If
End If
DateTime is a very flexible type which allows you to easily perform many date/time related actions. You don't need to perform a string-like analysis (what your code is doing).
For example, to take care of the two requested functionalities, just do something like:
Dim curTime As DateTime = Now
Dim goAhead As Boolean = True
If curTime.DayOfWeek = DayOfWeek.Saturday OrElse curTime.DayOfWeek = DayOfWeek.Sunday Then
goAhead = False
ElseIf curTime > New DateTime(curTime.Year, curTime.Month, curTime.Day, 14, 30, 0) Then
goAhead = False
End If
If goAhead Then
'Weekday before 2:30 PM
End If

offset for weekend days using mod

I have a .NET console app that needs to run on the 1st, 5th, 10th, 15th, 20th, and 25th of each month. Depending on which date it runs, the app sends out a different type of email. I want to adjust the app so that if one of those dates is on the weekend, it runs the following Monday.
I believe this does what I want:
Dim adjustedDay As Integer = Day(Today)
If Today.ToString("ddd") = "Mon" And adjustedDay > 1 Then
If adjustedDay Mod 5 = 1 Then
adjustedDay -= 1
ElseIf adjustedDay Mod 5 = 2 Then
adjustedDay -= 2
End If
End If
Select Case adjustedDay
Case 1
...
Case 5
...
Case ...
...
End Select
So if today is Monday, 9/21/2015, I adjust to "20" and run that code. If Monday happens to land on the 1st, I don't adjust it.
is there a cleaner way to do this?
Your code won't work correctly if Monday falls on the 2nd or 3rd of the month. (ie. 2 mod 5 = 2, so adjustedDay = 0)
The other tricky part is that the app needs to run on the 1st, but 1 mod 5 = 1 which is different to all the other cases where it is 0.
Something like this should work:
'Returns 0 for non-email days, otherwise returns 1,5,10,15,20,25
Private Function GetEmailDay(ByVal currentDate as Date) As Integer
If currentDate.DayOfWeek = DayOfWeek.Saturday OrElse
currentDate.DayOfWeek = DayOfWeek.Sunday Then
Return 0
End If
Dim day As Integer = currentDate.Day
Dim emailDays As New List(Of Integer)( {1,5,10,15,20,25} )
If emailDays.Contains(day) Then
Return day
End If
If currentDate.DayOfWeek = DayOfWeek.Monday Then
If emailDays.Contains(day-1) Then 'check Sunday
Return day-1
End If
If emailDays.Contains(day-2) Then 'check Saturday
Return day-2
End If
End If
Return 0
End Function

how to compare 2 datetimepicker vb.net

I'd like to compare 2 DateTimePicker's value
Dim dd1 As Date, dd2 As Date
Dim diff As Integer
dd1 = DateTimePicker1.Value
dd2 = DateTimePicker2.Value
diff = DateDiff("d", dd1, dd2)
If diff > 0 Then
MsgBox("datetimpicker1datetimepicker2")
End If
but it doesn't work could you help me please
Another way to compare would be to use the DateTime.Compare function. For a simple "Are they the same?" you could try:
If Not DateTime.Compare(dd1,dd2) = 0 then
'they are diffent
End If
Or if you want to be more specific then you might go with something like this:
If Not DateTime.Compare(dd1,dd2) = 0 then
'they are same
ElseIf DateTime.Compare(dd1,dd2) > 0 then
'dd1 is later than dd2
Else
'dd1 is prior to dd2
End If
You can see more about DateTime.Comare here on MSDN
If You are using DateDiff() then there are three case can be possible:-
1) DatePicker1 date is bigger than DatePicker2
2) DatePicker1 date is lower than DatePicker2
3) DatePicker1 date is equal to DatePicker2
To handle this, You have to use this
diff = DateDiff("d", dd1, dd2)
If diff > 0 Then
MsgBox("datetimpicker1 is greater than datetimepicker2")
Else If diff < 0 Then
MsgBox("datetimpicker1 is lesser than datetimepicker2")
Else
MsgBox("datetimpicker1 is equal to datetimepicker2")
End If

calculate date add, but only weekdays

I would like to calculate a new date simply by using the build-in dateadd function, but take into account that only weekdays should be counted (or 'business days' so to speak).
I have come up with this simple algorithm, which does not bother about holidays and such. I have tested this with some simple dates, but would like some input if this can be done in better ways.
This sample assumes a week with 5 business days, monday-friday, where first day of the week is monday. Dateformatting used here is d-m-yyyy, the sample calculates with a startdate of october 1, 2009.
Here is the simple form:
Dim d_StartDate As DateTime = "1-10-2009"
Dim i_NumberOfDays As Integer = 12
Dim i_CalculateNumberOfDays As Integer
If i_NumberOfDays > (5 - d_StartDate.DayOfWeek) Then
i_CalculateNumberOfDays = i_NumberOfDays
Else
i_CalculateNumberOfDays = i_NumberOfDays + (Int(((i_NumberOfDays + (7 - d_StartDate.DayOfWeek)) / 5)) * 2)
End If
MsgBox(DateAdd(DateInterval.Day, i_CalculateNumberOfDays, d_StartDate))
Which I try to explain with the following piece of code:
''' create variables to begin with
Dim d_StartDate as Date = "1-10-2009"
Dim i_NumberOfDays as Integer = 5
''' create var to store number of days to calculate with
Dim i_AddNumberOfDays as Integer
''' check if amount of businessdays to add exceeds the
''' amount of businessdays left in the week of the startdate
If i_NumberOfDays > (5 - d_StartDate.DayOfWeek) Then
''' start by substracting days in week with the current day,
''' to calculate the remainder of days left in the current week
i_AddNumberOfDays = 7 - d_StartDate.DayOfWeek
''' add the remainder of days in this week to the total
''' number of days we have to add to the date
i_AddNumberOfDays += i_NumberOfDays
''' divide by 5, because we need to know how many
''' business weeks we are dealing with
i_AddNumberOfDays = i_AddNumberOfDays / 5
''' multiply the integer of current business weeks by 2
''' those are the amount of days in the weekends we have
''' to add to the total
i_AddNumberOfDays = Int(i_AddNumberOfDays) * 2
''' add the number of days to the weekend days
i_AddNumberOfDays += i_NumberOfDays
Else
''' there are enough businessdays left in this week
''' to add the given amount of days
i_AddNumberOfDays = i_NumberOfDays
End If
''' this is the numberof dates to calculate with in DateAdd
dim d_CalculatedDate as Date
d_CalculatedDate = DateAdd(DateInterval.Day, i_AddNumberOfDays, d_StartDate)
Thanks in advance for your comments and input on this.
I used the .DayOfWeek function to check if it was a weekend. This does not include holiday implementation. It has been tested. I realize this question is old but the accepted answer didn't work. However, I did like how clean it was so I thought I'd update it and post. I did change the logic in the while loop.
Function AddBusinessDays(startDate As Date, numberOfDays As Integer) As Date
Dim newDate As Date = startDate
While numberOfDays > 0
newDate = newDate.AddDays(1)
If newDate.DayOfWeek() > 0 AndAlso newDate.DayOfWeek() < 6 Then '1-5 is Mon-Fri
numberOfDays -= 1
End If
End While
Return newDate
End Function
Public Shared Function AddBusinessDays(ByVal startDate As DateTime, _
ByVal businessDays As Integer) As DateTime
Dim di As Integer
Dim calendarDays As Integer
'''di: shift to Friday. If it's Sat or Sun don't shift'
di = (businessDays - Math.Max(0, (5 - startDate.DayOfWeek)))
''' Start = Friday -> add di/5 weeks -> end = Friday'
''' -> if the the remaining (<5 days) is > 0: add it + 2 days (Sat+Sun)'
''' -> shift back to initial day'
calendarDays = ((((di / 5) * 7) _
+ IIf(((di Mod 5) <> 0), (2 + (di Mod 5)), 0)) _
+ (5 - startDate.DayOfWeek))
Return startDate.AddDays(CDbl(calendarDays))
End Function
Your plan seems like it should work. Make sure you wrap it in a function instead of doing out the calculations every place you use it so that if/when you discover you need to account for holidays, you don't have to change it in tons of places.
The best way I can think of for implementing support for holidays would be to add days one at a time in a loop. Each iteration, check if its a weekend or a holiday, and if it is add another day and continue (to skip it). Below is an example in pseudocode (I don't know VB); no guarantees its correct. Of course, you need to provide your own implementations for isWeekend() and isHoliday().
function addBusinessDays(startDate, numDays)
{
Date newDate = startDate;
while (numDays > 0)
{
newDate.addDays(1);
if (newDate.isWeekend() || newDate.isHoliday())
continue;
numDays -= 1;
}
return newDate;
}
My first thought for the holiday thing was to simply look up the number of holidays between the start date and the end date and add that to your calculation, but of course this won't work because the end date is dependent on the number of holidays in that interval. I think an iterative solution is the best you'll get for holidays.
I'm using this code to calculate the date:
dayOfWeek = startDate.DayOfWeek
weekendDays = 2 * Math.Floor((dayOfWeek + businessDays - 0.1) / 5)
newDate = startDate.AddDays(businessDays + weekendDays)
The second line computes the number of full weekends that we have to add and then multiplies them by 2 to obtain the number of days.
The additional -0.1 constant is used to avoid adding days if (dayOfWeek + businessDays) is multiple of 5, and final date is friday.
Private Function AddBusinessDays(ByVal dtStartDate As DateTime, ByVal intVal As Integer) As DateTime
Dim dtTemp As DateTime = dtStartDate
dtTemp = dtStartDate.AddDays(intVal)
Select Case dtTemp.DayOfWeek
Case 0, 6
dtTemp = dtTemp.AddDays(2)
End Select
AddBusinessDays = dtTemp
End Function
please check this code for adding working days
Dim strDate As Date = DateTime.Now.Date
Dim afterAddDays As Date
Dim strResultDate As String
Dim n As Integer = 0
For i = 1 To 15
afterAddDays = strDate.AddDays(i)
If afterAddDays.DayOfWeek = DayOfWeek.Saturday Or afterAddDays.DayOfWeek = DayOfWeek.Sunday Then
n = n + 1
End If
Next
strResultDate = afterAddDays.AddDays(n).ToShortDateString()
Private Function AddXWorkingDays(noOfWorkingDaysToAdd As Integer) As Date
AddXWorkingDays = DateAdd(DateInterval.Weekday, noOfWorkingDaysToAdd + 2, Date.Today)
If Weekday(Today) + noOfWorkingDaysToAdd < 6 Then AddXWorkingDays = DateAdd(DateInterval.Weekday, 2, Date.Today)
End Function
One approach would be to iterate from the start date and add or subtract one day with each iteration if the date is not a Saturday or Sunday. If zero is passed as iAddDays then the function will return dDate even if that date is a Saturday or Sunday. You could play around with the logic to get the outcome you are looking for if that scenario is a possibility.
Public Function DateAddWeekDaysOnly(ByVal dDate As DateTime, ByVal iAddDays As Int32) As DateTime
If iAddDays <> 0 Then
Dim iIncrement As Int32 = If(iAddDays > 0, 1, -1)
Dim iCounter As Int32
Do
dDate = dDate.AddDays(iIncrement)
If dDate.DayOfWeek <> DayOfWeek.Saturday AndAlso dDate.DayOfWeek <> DayOfWeek.Sunday Then iCounter += iIncrement
Loop Until iCounter = iAddDays
End If
Return dDate
End Function
Easy way
function addWerktage($date,$tage){
for($t=0;$t<$tage;$t++){
$date = $date + (60*60*24);
if(date("w",$date) == 0 || date("w",$date) == 6){ $t--; }
}
return $date;
}
This produces the same result as the accepted answer, including starting on weekends, while handling negative offsets and without looping. It's written in c# but should work in any enviroment where numeric weekdays start at Sunday and end at Saturday, and where integer division rounds to 0.
public static DateTime AddWeekdays(DateTime date, int offset)
{
if (offset == 0)
{
return date;
}
// Used to calculate the number of weekend days skipped over
int weekends;
if (offset > 0)
{
if (date.DayOfWeek == DayOfWeek.Saturday)
{
// Monday is 1 weekday away, so it will take an extra day to reach the next weekend
int daysSinceMonday = -1;
// Add two weekends for every five days
int normalWeekends = (offset + daysSinceMonday) / 5 * 2;
// Add one for this Sunday
int partialWeekend = 1;
weekends = normalWeekends + partialWeekend;
}
else
{
// It will take this many fewer days to reach the next weekend.
// Note that this works for Sunday as well (offset -1, same as above)
int daysSinceMonday = date.DayOfWeek - DayOfWeek.Monday;
// Add two weekends for every five days (1 business week)
weekends = (offset + daysSinceMonday) / 5 * 2;
}
}
else
{
// Same as the positive offset case, but counting backwards.
// daysSinceFriday will be 0 or negative, except for Saturday, which is +1
int daysSinceFriday = date.DayOfWeek - DayOfWeek.Friday;
weekends = date.DayOfWeek == DayOfWeek.Sunday
? (offset + 1) / 5 * 2 - 1
: (offset + daysSinceFriday) / 5 * 2;
}
return date.AddDays(offset + weekends);
}
Since the pattern of 2 extra days per 5 days repeats after a full week, you can effectively exhaustively test it:
private static DateTime AddWeekdaysLooping(DateTime date, int offset)
{
DateTime newDate = date;
int step = Math.Sign(offset);
while (offset != 0)
{
newDate = newDate.AddDays(step);
if (newDate.DayOfWeek != DayOfWeek.Sunday && newDate.DayOfWeek != DayOfWeek.Saturday)
{
offset -= step;
}
}
return newDate;
}
void TestWeekdays()
{
DateTime initial = new DateTime(2001, 1, 1);
for (int day = 0; day < 7; day += 1)
{
for (int offset = -25; offset <= 25; offset += 1)
{
DateTime start = initial.AddDays(day);
DateTime expected = AddWeekdaysLooping(start, offset);
DateTime actual = AddWeekdays(start, offset);
if (expected != actual) {
throw new Exception($"{start.DayOfWeek} + {offset}: expected {expected:d}, but got {actual:d}");
}
}
}
}
Dim result As Date
result = DateAdd("d", 2, Today)
If result.DayOfWeek = DayOfWeek.Saturday Then
result = DateAdd("d", 2, result)
MsgBox(result)
ElseIf result.DayOfWeek = DayOfWeek.Sunday Then
result = DateAdd("d", 1, result)
MsgBox(result)
ElseIf result.DayOfWeek = DayOfWeek.Monday Then
MsgBox(result)
ElseIf result.DayOfWeek = DayOfWeek.Tuesday Then
MsgBox(result)
ElseIf result.DayOfWeek = DayOfWeek.Wednesday Then
MsgBox(result)
ElseIf result.DayOfWeek = DayOfWeek.Thursday Then
MsgBox(result)
ElseIf result.DayOfWeek = DayOfWeek.Friday Then
MsgBox(result)
End If