use NodaTime to calculate an inclusive days period
Question
So for example if I have the following code:
var nodaStart = new LocalDate(2012, 5, 1);
var nodaEnd = new LocalDate(2012,5,2);
var daysBetween = Period.Between(nodaStart, nodaEnd,PeriodUnits.Day);
Then daysBetween.Days == 1
However, the range I calculate needs to count that as 2 days. i.e. it needs to be inclusive of the start and end date.
The actual method can take and start and end date (that are no more than a year apart) and needs to calculate the number of days. If there are more than 31 days then the remainder are returned as a number of whole weeks.
I have that logic working fine but because the count is exclusive I'm one day out.
I guess I can just do startDate.addDays(-1)
before I create nodaStart
from it but I wonder if there's a more elegant / pretty way to have noda return the Period.
Thanks
UPDATE:
I've had a read of the source code for the Period
class and the +
operator is overloaded so I can add
daysBetween += Period.FromDays(1);
Solution
(Sorry it's taken me so long to answer this - I hadn't seen it before.)
Any of:
- Adding a day to the end before calculating (this is the most logical approach, IMO - as Roger says, you want the start of the next day, effectively)
- Subtracting a day from the start before calculating
- Adding 1 to the number of days you get out of the end
should be fine. I don't think Noda Time will change to make this any simpler. Between
is a sort of "fuzzy around units" version of a subtraction operator - and you won't find many subtraction operators where 2 - 1 is 2.
OTHER TIPS
For "fuzzy" brained humans, we may consider a period of days to be inclusive of start and end date if it identifies a single day, week, month, etc (cf. whole multiple of), so you could code it:
var start = new NodaTime.LocalDateTime(s.Year, s.Month, s.Day, s.Hour, s.Minute);
var end = new NodaTime.LocalDateTime(e.Year, e.Month, e.Day, e.Hour, e.Minute);
NodaTime.Period periodInclusive = NodaTime.Period.Between(start, end.PlusDays(1), NodaTime.PeriodUnits.AllDateUnits);
NodaTime.Period period = NodaTime.Period.Between(start, end, NodaTime.PeriodUnits.AllDateUnits);
bool isInclusivePeriod = periodInclusive.Days + periodInclusive.Weeks + periodInclusive.Months + periodInclusive.Years <
period.Days + period.Weeks + period.Months + period.Years;
period = isInclusivePeriod ? periodInclusive : period;
// do stuff with period here....