【问题标题】:How to get dates between two dates in C#如何在C#中获取两个日期之间的日期
【发布时间】:2021-10-20 19:16:52
【问题描述】:

我想获取两个日期之间的日期。我得到了 875287内存不足,而不是预期的 9 个不同的日期。下面的代码会有什么问题?

StartDate 的值为01/04/2016 00:00:00

EndDate 的值为10/04/2016 00:00:00

var selectedDates = new List<DateTime?>();

for (var date = StartDate; date <= EndDate; date.Value.AddDays(1))
{
    selectedDates.Add(date);
}

【问题讨论】:

标签: c# linq datetime


【解决方案1】:

您没有将date.Value.AddDays(1) 的值分配给任何东西,因此它最终陷入无限循环。您需要更改代码,以便将 date 设置为 AddDays 的结果。

for (var date = StartDate; date <= EndDate; date = date.AddDays(1))
{
    selectedDates.Add(date);
}

【讨论】:

  • 这个。与String 一样,对DateTime 对象的操作会返回一个新对象,而不是修改现有对象。
  • 根据 OP 的解释(这意味着这段代码可以编译和工作),这个 date 看起来像 DateTime?,而不是 DateTime,因为 DateTime 没有名为 Value 的属性。
  • 您更新的代码也无法编译,因为Nullable&lt;DateTime&gt; 没有名为AddDays 的方法。
【解决方案2】:

LINQ 解决方案(让我们生成 selectedDates):

  var selectedDates = Enumerable
    .Range(0, int.MaxValue)
    .Select(index => new DateTime?(StartDate.AddDays(index)))
    .TakeWhile(date => date <= EndDate)
    .ToList();

【讨论】:

  • 这是最好的答案,因为它避免了增量计算,这是一种反模式。甚至不确定AddDays(1) 的想法是否正确。
  • 为什么要新建一个DateTime??选择StartDate.AddDays(index)的返回值会有什么问题?
  • @AshBurlaczenko: StartDate.AddDays 的返回值为DateTime,但提问者在他的问题中使用了List&lt;DateTime?&gt;new DateTime? 只是将返回值强制为目标类型的一种方式。
  • @Mou:如果我没听错的话,你对我没有添加任何项目感到困惑。好吧,我没有添加现有列表var selectedDates = new List&lt;DateTime?&gt;(); for ... Add ...我只是创建它:在执行Linq查询@987654332之后@ 将显示为 List&lt;DateTime?&gt;,其中包含所需的日期
【解决方案3】:

据我所知,由于AddDays 方法返回DateTime 的新实例,它确实不会更改当前实例,因为DateTimeimmutable。 p>

看起来你的dateDateTime?,你可以把这部分改成;

for (var date = StartDate; date <= EndDate; date = date.Value.AddDays(1))
{
    selectedDates.Add(date);
}

正如 usr 所指出的,这可能会在夏令时受到影响。您可能还想查看Dmitry's answer

【讨论】:

  • 由于计算的增量性质,这没有错误吗?如果 StartDate 是凌晨 2:30,如果您遇到夏令时,时间将会发生变化。 AddDays 的行为不像整数。
  • @usr 你说得对,DateTime 结构在算术运算中考虑 DST。但根据 OP 的开始和结束日期,这不应该是这样。也更新了我对点 Dmitry 的回答的回答。谢谢。
  • 这个性能很糟糕,因为它会多次扩展列表。
【解决方案4】:

使用 Linq 的 Range 方法的更短的表示法使用 TimeSpan.Days 属性在从结束减去开始后已经计算出天数的能力。

假设 start 在 end 之前,你会得到:

DateTime StartDate = new DateTime(1979, 10, 4);
DateTime EndDate = new DateTime(2016, 10, 4);

var dates = Enumerable.Range(0, (EndDate - StartDate).Days + 1)
    .Select(day => StartDate.AddDays(day))

如果需要为 Nullable,请添加:

    .Cast<DateTime?>()

如果您需要将其作为列表,请添加:

    .ToList()

它可能比其他基于 LINQ 的解决方案更有效。

【讨论】:

    【解决方案5】:

    决定用 do/while 来改变它

    var selectedDates = new List<DateTime?>();
    DateTime? StartDate = DateTime.Parse("01/04/2016 00:00:00");
    DateTime? EndDate = DateTime.Parse("10/04/2016 00:00:00");
    
    do
    {
        selectedDates.Add(StartDate);
        StartDate = StartDate.Value.AddDays(1);
    }while(StartDate < EndDate);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-11
      • 2018-09-17
      • 1970-01-01
      • 1970-01-01
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      • 2015-04-24
      相关资源
      最近更新 更多