I have a data structure like this which holds start/end dates:

----|-----------|-----------
Item| start     | end
----|-----------|-----------
1   |2017-05-12 | 2017-05-12
2   |2017-05-12 | 2017-05-13
3   |2017-05-13 | 2017-05-13
4   |2017-05-13 | 2017-05-14
5   |2017-05-14 | 2017-05-15
6   |2017-05-15 | 2017-05-16
7   |2017-05-16 | 2017-05-16 

I want to move the start date of the first item to 2017-01-01 and every item should follow that start date and must stay within its ranges. The result should look like the following:

----|-----------|-----------
Item| start     | end
----|-----------|-----------
1   |2017-01-01 | 2017-01-01
2   |2017-01-01 | 2017-01-02
3   |2017-01-02 | 2017-01-02
4   |2017-01-02 | 2017-01-03
5   |2017-01-03 | 2017-01-04
6   |2017-01-04 | 2017-01-05
7   |2017-05-05 | 2017-05-05

This is how I implemented the method:

var items = booking.ActiveItems(); // each item has check-in and/or check-out dates

var tempCurrentDate = newStartDate;
var previousCheckoutDate = newStartDate;

// total days between booking date to first item date
// var bdToFid = 0;

// go thru each item
for (var i = 0; i < items.Count; i++)
{
    var currentItem = items[i];
    var itemCheckinDate = currentItem.CheckInDate();
    var itemCheckoutDate = currentItem.CheckOutDate(); 

    // no of days between check-out and check-in
    var checkinToCheckoutDifference = (itemCheckoutDate - itemCheckinDate).Days; 
    if (i == 0)
    {
        // check-in equals to start date if the item is the first one in the list
        itemCheckinDate = tempCurrentDate;
    }
    else
    {
        var prevDayToCurrentCheckinDifference = (previousCheckoutDate - currentItem.CheckInDate()).Days; 
        itemCheckinDate = tempCurrentDate.AddDays(prevDayToCurrentCheckinDifference);
    }

    currentItem.SetCheckInDate(itemCheckinDate);

    previousCheckoutDate = itemCheckoutDate;

    tempCurrentDate = itemCheckinDate.AddDays(checkinToCheckoutDifference);

    currentItem.SetCheckOutDate(tempCurrentDate); 
}

Even though this code works as expected, is there a better and efficient way of doing this?

share|improve this question
3  
Why can't you just substract a number of days from every date? I'm struggling to figure out what would contradict that – bushed 15 hours ago
    
@Paparazzi FWIW my moniker is Vogel612 :/ Sorry for the confusion, my chromium was so friendly as to use a non-fixed-width font for displaying monospace, which led me to believe that the table was misaligned ... – Vogel612 14 hours ago
var items = booking.ActiveItems(); // each item has check-in and/or check-out dates

var offset = items[0].GetCheckInDate().Date - DateTime.Parse("2017-05-12");

foreach(var item in items)
{
   item.SetCheckInDate(item.GetCheckInDate() - offset);
   item.SetCheckOutDate(item.GetCheckOutDate() - offset);
}

That, however would not account for e.g. holidays, weekends, availability

And the only reason to do iterative adjustmens (as in original code) would be if SetDate would automatically make adjustments to holidays/weekends inside.

In this case original code lacks comments around that area explaining that SetDate might change the date by itself and absolute day offset would change.

share|improve this answer

Some quick remarks:

  • Be consistent in naming. You mix both CheckOut and Checkout. Ditto for CheckIn vs Checkin.
  • Why are CheckInDate() and CheckOutDate() methods? They should be properties. (Or you should rename each so they start with "Get" -- but really, they should be properties.)
  • tempCurrentDate is not a good name for what it represents.
  • Why did you prefix itemCheckinDate and itemCheckoutDate with "item"? Why not simply use checkinDate and checkoutDate?
  • Comments should tell me why, not what. // no of days between check-out and check-in doesn't tell me anything the code doesn't.
  • Don't needlessly abbreviate: "prevDay" in prevDayToCurrentCheckinDifference is unclear.

Your flow is very hard to follow and seems needlessly complicated. I'd for instance leave SetCheckInDate and SetCheckOutDate to the very end instead of splitting them up. Make your flow easier to follow:

  1. store existing dates in local variables
  2. update local variables
  3. update booking

Or even simpler:

        var earliestCheckInDate = items.Min(x => x.CheckInDate());
        var daysToSubtract = (newStartDate - earliestCheckInDate).Days;

        foreach (var item in items)
        {
            var incorrectCheckInDate = item.CheckInDate();
            var incorrectCheckOutDate = item.CheckOutDate();

            item.SetCheckInDate(incorrectCheckInDate.AddDays(daysToSubtract));
            item.SetCheckOutDate(incorrectCheckOutDate.AddDays(daysToSubtract));
        }
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.