gpt4 book ai didi

c# - Linq 查询求和范围内的日期

转载 作者:太空宇宙 更新时间:2023-11-03 14:22:26 29 4
gpt4 key购买 nike

尝试找出是否有一个很好的方法来做到这一点,最好是在 Linq 中而不是循环中,这就是我现在所做的。

我想要我的产品在两个日期之间的活跃天数。

Product 有很多 ProductHistories,ProductHistory 有 DateActive 和 DateInactive 的值。 DateInactive 可以为 null,而且通常为 null,以表明此历史记录正在进行中。历史不会重叠。

我想对 startDate 或 ProductHistory 的 DateActive 的最大值求和,然后从 endDate 或 ProductHistory 的 DateInactive 的最小值总和中减去该总和(如果 DateInactive 没有值,则默认为 endDate)。

工作示例:

获取 2011-01-01(1 月 1 日)和 2011-02-01(2 月 1 日)之间的活跃天数

历史:

Active 2010-12-25 : Inactive 2011-01-05
Active 2011-01-15 : Inactive 2011-01-20
Active 2011-01-25 : Inactive null

总共应该有 16 天(4 + 5 + 7)

我现在最好的是相当丑陋:

    Dim a As Integer = (From h In histories
Select If(h.ActiveDate > startDate, h.ActiveDate, startDate)).Sum(Function(d) d.Ticks) / TimeSpan.TicksPerDay

Dim b As 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 - a

有什么想法吗? (C#或者VB都可以,我来翻译)

最佳答案

是这样的吗? (假设没有重叠的历史)

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 we are doing start - end
.Days);
  1. 只考虑在日期范围内开始的历史。
  2. 对于每个历史记录,将时间跨度构建为事件日期与非事件日期和结束日期的较早之间的差值。
  3. 总结一下。

为了改善这一点,我建议:

  1. 编写一个 IsBetween 扩展,让您可以将 where lambda 写为 ph.Active.IsBetween(start, end)
  2. 将 sum lambda 提取到不同的方法中,并更直观地编写它。在 DateTime? 上使用了“提升”运算符,许多人会觉得这很不直观。

关于c# - Linq 查询求和范围内的日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4947996/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com