# Date manipulation

356 Reputation points
2022-12-23T15:27:23.12+00:00

Hi,

assuming I work on this following scheme
5 morning shifts - 1 day off - 5 afternoon shifts - 1 day off - 5 night shifts - 1 day off

would it be possible using a date time picker control to know which shift will I be working on a selected date?
much thanks

VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,689 questions

1. 52,236 Reputation points
2022-12-23T16:38:00.9+00:00

Yes but you don't have sufficient information given that algorithm to answer the question. Without a start date (which can be variable) there is no way to do the calculation. But let's assume that you select a start date (e.g. 1/1/23). In that case 1/1-1/5 would be morning shifts, 1/6 would be a day off, 1/7-1/11 would be afternoon, 1/12 day off, 1/13-17 evening, 1/18 day off. Now that you have the selected date ranges you can just do a day diff on the selected date from the start date. For example if the diff is less than 5 then it is morning, = (6, 12, 18) then off, etc. (might be a off by one error in there...)

The harder problem to solve, for me, is how you're going to represent that scheme in a reasonable way. If you can ensure your scheme always is simple like this then date diffs will work just fine. But if you might have a mixture of shifts then it becomes harder to do simple date diffs and date comparisons are probably easier.

var shifts = GenerateShifts(new DateTime(2023, 1, 1));

foreach (var shift in shifts)
Console.WriteLine(shift);

var selectedDate = new DateTime(2023, 1, 8);

Console.WriteLine("Shift selected");

var dateShift = shifts.Where(x => x.Contains(selectedDate));
foreach (var shift in dateShift)
Console.WriteLine(shift);

static IEnumerable<Shift> GenerateShifts ( DateTime startDate )
{
yield return new Shift() { StartDate = startDate, EndDate = startDate.AddDays(5), Kind = ShiftKind.Morning };

yield return new Shift() { StartDate = startDate.AddDays(6), EndDate = startDate.AddDays(6), Kind = ShiftKind.Off };

yield return new Shift() { StartDate = startDate.AddDays(7), EndDate = startDate.AddDays(11), Kind = ShiftKind.Afternoon };

yield return new Shift() { StartDate = startDate.AddDays(12), EndDate = startDate.AddDays(12), Kind = ShiftKind.Off };

yield return new Shift() { StartDate = startDate.AddDays(13), EndDate = startDate.AddDays(17), Kind = ShiftKind.Night };

yield return new Shift() { StartDate = startDate.AddDays(18), EndDate = startDate.AddDays(18), Kind = ShiftKind.Off };
}

public struct Shift
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public ShiftKind Kind { get; set; }

public bool Contains ( DateTime date ) => date >= StartDate && date <= EndDate;

public override string ToString () => \$"{StartDate} - {EndDate} : {Kind}";
}

public enum ShiftKind
{
Off = 1,
Morning,
Afternoon,
Night
}

1. 356 Reputation points
2022-12-23T17:36:33.44+00:00

Hi @Michael Taylor , using the following code It doesn't reproduce any msgbox.. What am i doing wrong?
Public Class Form1

Private Sub DisplayShifts()
Dim shifts = GenerateShifts(New DateTime(2023, 1, 1))
Dim selectedDate = New DateTime(2023, 1, 8)
Dim dateShift = shifts.Where(Function(x) x.Contains(selectedDate))
End Sub
Iterator Function GenerateShifts(startDate As Date) As IEnumerable(Of Shift)
Yield New Shift() With {.StartDate = startDate, .EndDate = startDate.AddDays(5), .Kind = ShiftKind.Morning}
Yield New Shift() With {.StartDate = startDate.AddDays(6), .EndDate = startDate.AddDays(6), .Kind = ShiftKind.Off}
Yield New Shift() With {.StartDate = startDate.AddDays(7), .EndDate = startDate.AddDays(11), .Kind = ShiftKind.Afternoon}
Yield New Shift() With {.StartDate = startDate.AddDays(12), .EndDate = startDate.AddDays(12), .Kind = ShiftKind.Off}
Yield New Shift() With {.StartDate = startDate.AddDays(13), .EndDate = startDate.AddDays(17), .Kind = ShiftKind.Night}
Yield New Shift() With {.StartDate = startDate.AddDays(18), .EndDate = startDate.AddDays(18), .Kind = ShiftKind.Off}
End Function
Public Structure Shift
Public Property StartDate As Date
Public Property EndDate As Date
Public Property Kind As ShiftKind
Public Function Contains(value As Date) As Boolean
Return value >= StartDate AndAlso value <= EndDate
End Function

End Structure
Public Enum ShiftKind
Off = 1
Morning
Afternoon
Night
End Enum

Private Sub Button1_Click(sender As Object, e As EventArgs)
MsgBox("{StartDate} - {EndDate} : {Kind}")
End Sub
End Class

much thanks

2. 356 Reputation points
2022-12-23T18:27:46.347+00:00

ok so the code is
Public Class Form1

Private Sub DisplayShifts()
Dim shifts = GenerateShifts(New DateTime(2023, 1, 1))
Dim selectedDate = New DateTime(2023, 1, 8)
Dim dateShift = shifts.Where(Function(x) x.Contains(selectedDate))
MsgBox(dateShift.ToString())
End Sub
Iterator Function GenerateShifts(startDate As Date) As IEnumerable(Of Shift)
Yield New Shift() With {.StartDate = startDate, .EndDate = startDate.AddDays(5), .Kind = ShiftKind.Morning}
Yield New Shift() With {.StartDate = startDate.AddDays(6), .EndDate = startDate.AddDays(6), .Kind = ShiftKind.Off}
Yield New Shift() With {.StartDate = startDate.AddDays(7), .EndDate = startDate.AddDays(11), .Kind = ShiftKind.Afternoon}
Yield New Shift() With {.StartDate = startDate.AddDays(12), .EndDate = startDate.AddDays(12), .Kind = ShiftKind.Off}
Yield New Shift() With {.StartDate = startDate.AddDays(13), .EndDate = startDate.AddDays(17), .Kind = ShiftKind.Night}
Yield New Shift() With {.StartDate = startDate.AddDays(18), .EndDate = startDate.AddDays(18), .Kind = ShiftKind.Off}
End Function
Public Structure Shift
Public Property StartDate As Date
Public Property EndDate As Date
Public Property Kind As ShiftKind
Public Function Contains(value As Date) As Boolean
Return value >= StartDate AndAlso value <= EndDate
End Function
Public Overrides Function ToString() As String
Return \$"{StartDate} - {EndDate} : {Kind}"
End Function
End Structure
Public Enum ShiftKind
Off = 1
Morning
Afternoon
Night
End Enum

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
DisplayShifts()
End Sub
End Class

but I'm getting the error

where "Ikariam" is the project name...

3. 356 Reputation points
2022-12-23T21:30:54.587+00:00

@Michael Taylor
do you mean something like this?

Public Class Form1

Private Sub DisplayShifts()
Dim startdate = New DateTime(2023, 1, 1)
Dim selectedDate = New DateTime(2023, 3, 9)

MsgBox(ShiftKind.Off.ToString())
End Sub
Function GetShift(startDate As Date, selectedDate As Date) As ShiftKind
Dim days = (selectedDate - startDate).TotalDays
Dim intervals = days \ 18
Dim normalizedSelected = selectedDate.AddDays(intervals * -18)
days = (normalizedSelected - startDate).TotalDays
Select Case days
Case 0 To 4
Return ShiftKind.Morning
Case 6 To 10
Return ShiftKind.Afternoon
Case 12 To 16
Return ShiftKind.Night
End Select
Return ShiftKind.Off
End Function
Public Structure Shift
Public Property StartDate As Date
Public Property EndDate As Date
Public Property Kind As ShiftKind
Public Function Contains(value As Date) As Boolean
Return value >= StartDate AndAlso value <= EndDate
End Function
Public Overrides Function ToString() As String
Return \$"{StartDate} - {EndDate} : {Kind}"
End Function
End Structure
Public Enum ShiftKind
Off = 1
Morning
Afternoon
Night
End Enum

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
DisplayShifts()
End Sub
End Class

if yes it returns off everytime :\