0

I have the following netfiddle:

.net fiddle

How can I make it work by adding a period that spans over midnight like this:

`new Period( "9", Days.Workdays, TimeSpan.FromHours(22), TimeSpan.FromHours(07) )`

Notice from 22:00 (10:00 PM) to 07:00 (07:00 AM)

user2818430
  • 5,853
  • 21
  • 82
  • 148
  • Why are you using two `TimeSpan`s to represent a single span of time? – Andrew Sep 05 '17 at 22:31
  • To help get people to answer, it'd be best to post a minimal code example in your question instead of linking externally. – John M. Wright Sep 05 '17 at 22:32
  • 1
    Hi. Please read [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) It's good that you have code in your fiddle, but you should show here the specific portion you need help with so your question is clear. For example, if it's just about doing a time-of-day range query that can cover spans over midnight, include your range query here in the question. Thanks. – Matt Johnson-Pint Sep 05 '17 at 22:32
  • 1
    @AndrewPiliser - they're not. They're using `TimeSpan` as a time-of-day instead of it's traditional usage as elapsed-time. This is yet another example of why a `TimeOfDay` type should exist natively in .NET. – Matt Johnson-Pint Sep 05 '17 at 22:34

2 Answers2

2

Matt has the right answer above, but a couple changes:

First, you need to make sure you have parentheses (hence your memory problem):

var period = _periods.Where(e => e.Days.HasFlag(day) && (e.Start <= e.End ? (e.Start <= timeOfDay && e.End > timeOfDay) : (e.Start <= timeOfDay || e.End > timeOfDay))).FirstOrDefault();

Second, in your GetShiftPeriods method, you need to shift by a day (simply adding period.End won't work in this scenario because that would just be "7hrs" instead of 7 in the morning.

        var next = current.Date + period.End;
        if (period.End < period.Start)
        {
            next = next.AddDays(1);
        }

Lastly, you have some overlap in your periods that you've defined. It works fine for me when I remove period #4 (comment out) with the two changes above. Not sure if you intended to have overlap, but if you do - that period will be ignored.

David Kujawski
  • 319
  • 1
  • 7
1

Assuming your question is about this part of your code:

e.Start <= timeOfDay && e.End > timeOfDay

You can change that to the following to account for time ranges over midnight:

e.Start <= e.End                                   // Are times in sequence?
    ? (e.Start <= timeOfDay && e.End > timeOfDay)  // Yes - standard calculation (AND)
    : (e.Start <= timeOfDay || e.End > timeOfDay)  // No - inverse calculation (OR)
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • seams to go in an endless loop inside GetShiftPeriods ` while (current < end)` – user2818430 Sep 05 '17 at 22:42
  • You need an extra set of parenthesis around the expression to isolate it from the other terms. Also, pleas go back and edit your question to include the code, as requested. Thanks. – Matt Johnson-Pint Sep 05 '17 at 22:52
  • Note even with the change, your code is not returning that shift. You have some other errors in your logic you'll need to debug. – Matt Johnson-Pint Sep 05 '17 at 23:01
  • I'll update the question. One more thing: Am I missing something? Because in the example from .netfiddle, there should be 3 shifts in Period 9: 4,5,and 7 of January 2017 .... – user2818430 Sep 05 '17 at 23:01
  • Yes, there are some additional errors in your code. I'd guess in your `GetShiftPeriods` method. Create some unit tests, and debug. Sorry, but I don't have time to do it for you. The code I gave here is indeed the correct technique for value-in-range for time-only ranges spanning midnight. Hope it is useful to you. – Matt Johnson-Pint Sep 05 '17 at 23:03
  • Thnaks for your help, I didn't see your previous comment. I also think the problem is in GetShiftPeriods. – user2818430 Sep 05 '17 at 23:07