c# - Linq query summing dates in range -
trying work out if there's nice way of doing this, preferably in linq rather loops, i've done now.
i want number of days product active between 2 dates.
product has many producthistories, producthistory has values dateactive , dateinactive. dateinactive can null, , be, show history ongoing. histories won't overlap.
i want sum maximum of startdate or producthistory's dateactive, , subtract total sum of minimum of enddate or producthistory's dateinactive (enddate default if dateinactive has no value).
worked example:
get active number of active days between 2011-01-01 (1st jan) , 2011-02-01 (1st feb)
histories:
active 2010-12-25 : inactive 2011-01-05 active 2011-01-15 : inactive 2011-01-20 active 2011-01-25 : inactive null
this should total 16 days (4 + 5 + 7)
my best @ moment rather ugly:
dim integer = (from h in histories select if(h.activedate > startdate, h.activedate, startdate)).sum(function(d) d.ticks) / timespan.ticksperday dim b integer = (from h in histories select if(h.inactivedate.hasvalue andalso h.inactivedate < enddate, h.inactivedate, enddate)).sum(function(d) d.value.ticks) / timespan.ticksperday return b -
any thoughts? (either c# or vb fine, i'll translate)
something this? (assumes no overlapping histories)
var numdays = product .producthistories .where(ph => ph.active >= start && ph.active < end) .sum(ph => ph.active .subtract(end > ph.inactive ? ph.inactive.value : end) .duration() // because doing start - end .days);
- only consider histories start within date-range.
- for each history, construct timespan delta between active-date , earlier of inactive-date , end-date.
- sum them up.
to improve this, suggest:
- write
isbetween
extension let write lambdaph.active.isbetween(start, end)
. - extract sum lambda out different method, , write more intuitively. there's use of "lifted" operator on
datetime?
many find quite unintuitive.
Comments
Post a Comment