Click here to Skip to main content
15,881,172 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I wanted to get of possible date ranges from a list of data range.
Ex:
1. Below date ranges (startdate, enddate)  
2021-01-01 00:00:00, 2021-01-13 23:59:59  
2021-01-07 00:00:00, 2021-02-03 23:59:59

will output 3 list as below  
2021-01-01 00:00:00, 2021-01-06 23:59:59  
2021-01-07 00:00:00, 2021-01-13 23:59:59   
2021-01-14 00:00:00, 2021-02-03 23:59:59

2. Below date ranges  (startdate, enddate)  
2021-01-01 00:00:00, 2021-01-13 23:59:59   
2021-01-02 00:00:00, 2021-01-03 23:59:59

will output 3 list as below  
2021-01-01 00:00:00, 2021-01-01 23:59:59  
2021-01-02 00:00:00, 2021-01-03 23:59:59   
2021-01-04 00:00:00, 2021-01-13 23:59:59

3. Below 2 date range in a list (startdate, enddate)  
2021-01-10 00:00:00, 2021-01-30 23:59:59   
2021-02-13 00:00:00, 2021-02-26 23:59:59

will output the same 2 records are there is no overlap.

Any help would be really appreciated.


What I have tried:

What i tried is, i got the starting date and ending date of each of the list item.
Then sort it and then create a new list tuple of dates with 1st and 2nd in the list

<pre>Dim lstDateRanges As New List(Of Tuple(Of Date, Date))
        Dim lstDates As New List(Of Date)
        Dim lstNewDateRanges As New List(Of Tuple(Of Date, Date))
        'lstDateRanges.Add(Tuple.Create(CDate("2021-01-01 00:00:00"), CDate("2021-01-13 23:59:59")))
        'lstDateRanges.Add(Tuple.Create(CDate("2021-01-02 00:00:00"), CDate("2021-01-03 23:59:59")))

        'lstDateRanges.Add(Tuple.Create(CDate("2021-01-01 00:00:00"), CDate("2021-01-13 23:59:59")))
        'lstDateRanges.Add(Tuple.Create(CDate("2021-01-07 00:00:00"), CDate("2021-02-03 23:59:59")))

        lstDateRanges.Add(Tuple.Create(CDate("2021-01-01 00:00:00"), CDate("2021-01-13 23:59:59")))
        lstDateRanges.Add(Tuple.Create(CDate("2021-01-15 00:00:00"), CDate("2021-02-03 23:59:59")))


        For Each dDate In lstDateRanges
            lstDates.Add(dDate.Item1)
            lstDates.Add(dDate.Item2)
        Next

        lstDates.Sort()
        For i As Int32 = 0 To lstDates.Count - 2
            If lstDates(i) <> lstDates(i + 1) Then 'ignore the same starting and ending dates
                If i = 0 Then
                    lstNewDateRanges.Add(Tuple.Create(lstDates(i), lstDates(i + 1).Date.AddSeconds(-1)))
                ElseIf i = lstDates.Count - 2 Then
                    lstNewDateRanges.Add(Tuple.Create(lstDates(i).AddSeconds(1), lstDates(i + 1).Date.AddDays(1).AddSeconds(-1)))
                Else
                    lstNewDateRanges.Add(Tuple.Create(lstDates(i), lstDates(i + 1).Date.AddDays(1).AddSeconds(-1)))
                End If
            End If
        Next


But this is not returning correct data. It is returning data fine when there is an overlap.
So first 2 test scenarios work fine. But the 3rd scenario is returning data incorrectly.
Please advise.
Posted
Updated 19-Apr-21 11:27am
v4

"It's not working" is one of the most useless problem descriptions we get: it tells us absolutely nothing about the problem. We don't know if you get an error message, or the wrong data, or even that that code compiles successfully!
Remember that we can't see your screen, access your HDD, or read your mind - we only get exactly what you type to work with.
So tell us what happens when you run that code, what you expected to happen, how you checked what happened. Help us to help you!

And before you even do that, think about what it is supposed to do, and look closely at what it does do - because compiling does not mean your code is right! :laugh:
Think of the development process as writing an email: compiling successfully means that you wrote the email in the right language - English, rather than German for example - not that the email contained the message you wanted to send.

So now you enter the second stage of development (in reality it's the fourth or fifth, but you'll come to the earlier stages later): Testing and Debugging.

Start by looking at what it does do, and how that differs from what you wanted. This is important, because it give you information as to why it's doing it. For example, if a program is intended to let the user enter a number and it doubles it and prints the answer, then if the input / output was like this:
Input   Expected output    Actual output
  1            2                 1
  2            4                 4
  3            6                 9
  4            8                16
Then it's fairly obvious that the problem is with the bit which doubles it - it's not adding itself to itself, or multiplying it by 2, it's multiplying it by itself and returning the square of the input.
So with that, you can look at the code and it's obvious that it's somewhere here:
VB
Private Function Double(ByVal value As Integer) As Integer
    Return value * value
End Function

Once you have an idea what might be going wrong, start using the debugger to find out why. Put a breakpoint on the first line of the method, and run your app. When it reaches the breakpoint, the debugger will stop, and hand control over to you. You can now run your code line-by-line (called "single stepping") and look at (or even change) variable contents as necessary (heck, you can even change the code and try again if you need to).
Think about what each line in the code should do before you execute it, and compare that to what it actually did when you use the "Step over" button to execute each line in turn. Did it do what you expect? If so, move on to the next line.
If not, why not? How does it differ?
Hopefully, that should help you locate which part of that code has a problem, and what the problem is.
This is a skill, and it's one which is well worth developing as it helps you in the real world as well as in development. And like all skills, it only improves by use!
 
Share this answer
 
Comments
Member 4581741 18-Apr-21 11:05am    
I know how to debug but i feel the way i am approaching the problem is wrong. You can review my code. Any suggestions regarding my initial question, how to solve or what approach should i take in solving that specific problem would be helpful. Thanks
OriginalGriff 18-Apr-21 11:20am    
So start with the debugger and look at exactly what is going on while your code runs.
You know the code better than we do, so if you know how to debug,why haven't you already?
Member 4581741 18-Apr-21 17:28pm    
I have updated code a little. Please check my updated post. I have posted results.
NVM, I was able to write the algorithm to get the datetime ranges:

VB
<pre>   Dim lstDateRanges As New List(Of Tuple(Of Date, Date))
        Dim lstDates As New List(Of Date)
        Dim lstNewDateRanges As New List(Of Tuple(Of Date, Date))

        lstDateRanges.Add(Tuple.Create(CDate("2021-01-01"), CDate("2021-01-13")))
        lstDateRanges.Add(Tuple.Create(CDate("2021-01-02"), CDate("2021-01-03")))

        '2nd test scenario
        'lstDateRanges.Add(Tuple.Create(CDate("2021-01-01"), CDate("2021-01-13")))
        'lstDateRanges.Add(Tuple.Create(CDate("2021-01-07"), CDate("2021-02-03")))

        '3nd test scenario
        'lstDateRanges.Add(Tuple.Create(CDate("2021-01-01"), CDate("2021-01-13")))
        'lstDateRanges.Add(Tuple.Create(CDate("2021-01-15"), CDate("2021-02-03")))

        '4nd test scenario
        'lstDateRanges.Add(Tuple.Create(CDate("2021-01-01"), CDate("2021-01-07")))
        'lstDateRanges.Add(Tuple.Create(CDate("2021-01-01"), CDate("2021-01-15")))

        For Each dDate In lstDateRanges
            lstDates.Add(dDate.Item1)
            lstDates.Add(dDate.Item2)
        Next

        lstDates.Sort()
       
        For i As Int32 = 0 To lstDates.Count - 2
            If lstDates(i) <> lstDates(i + 1) Then 'ignore the same starting and ending dates
                lstNewDateRanges.Add(Tuple.Create(lstDates(i).Date, lstDates(i + 1).Date.AddDays(1).AddSeconds(-1)))
            End If
        Next

        For Each newRange In lstNewDateRanges.ToList
            Dim bOverlapAny = False
            For Each oldRange In lstDateRanges
                If DoDateRangesOverlap(newRange.Item1.Date.AddSeconds(1), newRange.Item2.Date.AddSeconds(-1), oldRange.Item1.Date, oldRange.Item2.Date) Then
                    bOverlapAny = True
                    Exit For
                End If
            Next
            If Not bOverlapAny Then lstNewDateRanges.Remove(newRange)
        Next



Your welcome!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900