adding time segments

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi just wondering if anyone had any ideas on how to do this in C#.

I am trying to get the total time of several start and stop time data
entries. For example the input data looks like
starttime endtime
3:00pm 4:00pm
6:00pm 7:00pm.
6:30pm 7:00pm
3:00pm 3:30pm
It would be easy but I do not want to count any overlapped times. For
example for the data above I would want a sum of 2 hours, not counting the
6:30-7:00 segment and the 3:00-3:30 segment. Most of the data is more
complexed than the example above, more data entries with several different
overlaps. I currently have a loop and am comparing the current entry with
the previous entries. This works ok until I get to the 3:00-3:30 segment as
it does not know to not count it since it is only comparing it with the
6:30-7:00 segment.
thanks!
 
Hi Paul,

Using DateTime for the times, you can easily test if one span is within the boundaries of another and then just merge the two
 
Hi thanks for the quick response. Guess I am not quite sure how to set up
the comparison since it seems like it might have to change dynamically. It
gets a bit complicated for example as shown below. I think I would have to
store all merges and then with each new time segment I would need to compare
it to all of the saved time segments, so not quite sure how to set this up in
a loop.

typical data

start time end time
1 2
4 5
8 9:30
10 11:20
1:15 1:45
4:15 4:45
7:45 8:15
9:30 10:10
 
Paul said:
[...]
I currently have a loop and am comparing the current entry with
the previous entries. This works ok until I get to the 3:00-3:30 segment as
it does not know to not count it since it is only comparing it with the
6:30-7:00 segment.

Can we assume that all of the times being considered are either on the
same date, or include the date information?

It seems to me that the most straightforward implementation would be to
keep some kind of list of "DateTime with range" instances. In other
words, instances of a class that looks something like this:

class DateTimeRange
{
DateTime _dtStart;
DateTime _dtEnd;

public DateTimeRange(DateTime dtStart, DateTime dtEnd)
{
_dtStart = dtStart;
_dtEnd = dtEnd;
}
}

You'd start with an empty list. Each time you add a new time range (eg
"starting at 3pm, ending at 4pm", you would scan the list, looking for a
place to insert it. If there's overlap, you would modify the existing
entry in your list, expanding it to include the new entry. You do this
for each entry in your list of time ranges. When you're done, you
simply enumerate the list and extract the final start/end time values
from the list.

You'll have a variety of cases to deal with. The overlap could involve
the new range ending within an existing range, beginning within an
existing range, being completely contained within an existing range,
completely containing an existing range, or even spanning two existing
ranges.

I think a general-purpose way of dealing with those cases would be to
implement the code so that you simply check for any kind of overlap, and
once you find overlap, you remove the existing range from the list,
merge it as needed with the new range, and then re-add the result to
your list, handling the newly created range just as you would an original.

Conceptually I think that implementing that recursively would be
easiest, but it's not actually required.

Hope that helps.

Pete
 
An alternative to this could be tracking a DateTime and a timespan --
using the DateTime as your anchor (start, end, or possibly you could
switch between them).

Chris.
 
Chris said:
An alternative to this could be tracking a DateTime and a timespan --
using the DateTime as your anchor (start, end, or possibly you could
switch between them).

My newsreader is buggy, so I'm not sure if you're responding to my post
or not. In the thread view, it looks like you are, but I never really
know if there's no quoted text. :) But, assuming you are...

I personally think that using a DateTime as an anchor with TimeSpan for
length conceptually "feels" better. However, the original data is all
actual times, and I think that in reality the implementation is the same
except for what sort of conversions you need to do. Using only DateTime
values, given that the original data is also only using things that
essentially map to DateTime values likely will minimize the excess code
put in just to handle converting back and forth.

I definitely wouldn't bother making the DateTime anchor be able to be
the start or end, with a positive or negative TimeSpan. I've had to
write code like that before, in scenarios where it actually is
necessary, and it can be a pain. It's much nicer to be able to just
assume that the anchor is at the beginning of the range.

Of course, if the range is always just a start and end time, as I
proposed, the question of which end the anchor is on goes away. Perhaps
that's another good reason to stick with keeping the internal
representation the same as the input data. :)

Pete
 
Peter said:
My newsreader is buggy, so I'm not sure if you're responding to my post
or not. In the thread view, it looks like you are, but I never really
know if there's no quoted text. :) But, assuming you are...

Yup, it was. Apologies for not quoting your post.
I personally think that using a DateTime as an anchor with TimeSpan for
length conceptually "feels" better. However, the original data is all
actual times, and I think that in reality the implementation is the same
except for what sort of conversions you need to do. Using only DateTime
values, given that the original data is also only using things that
essentially map to DateTime values likely will minimize the excess code
put in just to handle converting back and forth.

True enough. I was just tossing the idea out there. It's not like you
can't just subtract start from end and get your TimeSpan anyways. :)
I definitely wouldn't bother making the DateTime anchor be able to be
the start or end, with a positive or negative TimeSpan. I've had to
write code like that before, in scenarios where it actually is
necessary, and it can be a pain. It's much nicer to be able to just
assume that the anchor is at the beginning of the range.

Agreed. As with the other stuff, I was throwing it out there in the
"brainstorming" mindset.

Chris.
 
Thanks for all of the responses. I came up with the following which I think
closely follows the suggestions, but without using a time interval.

I sort all of the data based on the start time. I then loop through the
data and if the current time merges with the previous time I keep a running
min and max to handle these merges. When a new record is read into the
algorithm, if a merge is not detected I then save off the start and stop
times. If a merge is detected I do not save off the start and stop times but
adjust the running min and max.
 
Hi thanks for the quick response. Guess I am not quite sure how to set up
the comparison since it seems like it might have to change dynamically. It
gets a bit complicated for example as shown below. I think I would have to
store all merges and then with each new time segment I would need to compare
it to all of the saved time segments, so not quite sure how to set this up in
a loop.

typical data

start time end time
1 2
4 5
8 9:30
10 11:20
1:15 1:45
4:15 4:45
7:45 8:15
9:30 10:10

Try creating a class or struct holding two DateTime. Then create a list of all time spans using the struct/class to hold the times. If you sort if by start time it will be easier. Taking the first timespan in the list. Are there any other timespans having a start time earlier than this items end time. If so, merge them by adjusting the end time (might want to check if the end time is less than the first items end time). If no other items started in this timespan, store it as a unique timespan somewhere, do this as long as you have remaining items.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top