Having a tough time wrapping my head around this one. I am trying to make a study schedule for the user based on the days of the week they would select as the days they would plan to study. For example, if the user chooses to study only on Mondays, Wednesdays, and Thursdays, I would like to get the dates as such:
Monday: session 1
Wednesday: session 2
Thursday: session 3
next Monday: session 4
and so on…
I was thinking of using a DateInterval, and still think this is the way to go, but the date interval would be different for each of these days. M to W is DI 2. W to Th is DI 1. Th to M is DI 4
Without needing to have an enormous if…then for all possible scenarios, is there an easier way to accomplish this, considering also that of course, M W Th will not always be the selected study days?
i think its more or less a while wend loop with dateinterval of 1 day.
for the loop you could use a start and end date as range or a count of sessions.
you have a specification (could be a true/false array for weekdays) / condition when the day is ok or not and the output is a list of DateTime.
you need a class with a few methods and propertys to handle this.
With @MarkusR’s idea, you could improve it by computing the next wanted day. So, with your example of Mondays, Wednesdays and Thursdays, you can do something like that (example written from scratch, not tested in the IDE):
var Days() as Integer=Array(2,4,5) '2=Monday, 4=Wednesday, 5=Thursday; values defined like DateTime's DayOfWeek and must conform to it.
var CurrentDate as DateTime
//Init the date to the first day you want in this line. Must be on a day set in Days().
//Later, in the loop:
do
//Earlier code if you want, then:
var DayIndex as integer=Days.IndexOf(CurrentDate.DayOfWeek) 'Since CurrentDate would always be Monday, Wednesday or Thursday (or the set you'd have defined), we'd find its day index in the array
if DayIndex=-1 then
Break 'Should never happen, but for sake of safety, avoid infinite loops
//raise an exception
end if
var NextDay as Integer=Days((DayIndex+1) mod (Days.LastIndex+1) 'Get the next day in the array, or back to the first one if we're on the last
var DaysInterval=NextDay-DayIndex
if DaysInterval<0 then DaysInterval=DaysInterval+7 'Start again for next week
CurrentDate=CurrentDate.AddInterval(0,0,DaysInterval,0,0,0,0) 'Add the number of days. CurrentDate would always fall to the next day you want.
//Do something with CurrentDate; exit the loop when you're finished
Loop
Of course, you can have more or less days in the array (Days) and different days. Just fill Days with the days you need.
Here’s an extension method that will return the date of the next day of week passed.
Public Function DateOfNextDayOfWeek(Extends dt As DateTime, DayOfWeek As Integer) As DateTime
If DayOfWeek < 1 Or DayOfWeek > 7 Then
Var err As New InvalidArgumentException
err.Message = "A Day of week has been passed that is out of range 1-7"
Raise err
End If
Var Result As DateTime = dt.AddInterval(0, 0, If(dt.DayOfWeek < DayOfWeek, DayOfWeek - dt.DayOfWeek, (DayOfWeek + 7) - dt.DayOfWeek))
Return Result
End Function
Pop this into a module and your DateTime instances will now have the ability to return the date of say the next Wednesday after the Date by passing 4 as the DayOfWeek.
Private Function CreateDateSeries(fromDate As DateTime, toDate As DateTime, DayOfWeekAllowed() As Boolean) As DateTime()
Var dates() As DateTime
Var currentDate As DateTime = fromDate
Do
If DayOfWeekAllowed(currentDate.DayOfWeek) = True Then '1=Sunday, 7=Saturday
dates.AddRow(currentDate)
End If
currentDate = currentDate + New DateInterval(0,0,1) '+1 Day
Loop Until currentDate > toDate
Return dates
End Function
Test
Var fromDate As DateTime = DateTime.Now
Var toDate As DateTime = DateTime.Now + New DateInterval(0,3,0)
Var dates() As DateTime = CreateDateSeries(fromDate,toDate ,Array(False,False,True,False,True,False,True,False))
System.DebugLog fromDate.ToString(DateTime.FormatStyles.Full) + " - " + toDate.ToString(DateTime.FormatStyles.Full)
For Each d As DateTime In dates
System.DebugLog d.ToString(DateTime.FormatStyles.Full)
Next
Thank you all for the replies and sample code! I found that Markus’s solution worked the best for me. Really appreciate this. Spent much of yesterday afternoon trying out different ways but still just could not get it. All set now