Dart/Flutter: 日期范围内的日期列表

8

我需要从日期范围中检索日期列表。用户选择开始日期和结束日期,计算两个日期之间的天数(包括开始和结束日期)。

我尝试使用以下for循环:

List<DateTime> calculateDaysInterval(DateTime startDate, DateTime endDate) {
    List<DateTime> days = [];
    for (DateTime d = startDate;
        d.isBefore(endDate);
        d.add(Duration(days: 1))) {
      days.add(d);
    }
    return days;
  }

但它不起作用并且导致应用程序冻结。 你们有什么建议吗? 提前感谢。


var start = DateTime.now(); var end = DateTime.now().add(Duration(hours: 100)); var list = []; while (start.isBefore(end)) { list.add(start); start = start.add(Duration(days: 1)); } print(list); - pskink
5个回答

22

怎么样:

final daysToGenerate = end.difference(start).inDays;
days = List.generate(daysToGenerate, (i) => DateTime(start.year, start.month, start.day + (i)));

4
我喜欢这种方法,但会使用DateTime的add函数来添加天数,而不是直接添加天数,以避免在月份/年份之间出现问题。代码如下:List<DateTime> days = List.generate(daysToGenerate, (i) => start.add(Duration(days: i))) - alexbhandari
1
@alexbhandari 如果有什么问题,Rob的答案更好,因为使用Dart持续时间时,一天只是24小时,而实际上,一天有时可能是23或25小时。 - HJo
这个解决方案在接下来的两天内不起作用 ```//给定 var dateTimeStart = DateTime(2020, 1, 1); var dateTimeEnd = DateTime(2020, 1, 2);//当 var range = DateTimeRange(start: dateTimeStart, end: dateTimeEnd); List rangeList = range.calculateDaysInterval(); //那么 List expectedList = [dateTimeStart, dateTimeEnd]; expect(rangeList.length, expectedList.length);``` - Michał Jabłoński

9

我可能找到了一种解决方案。 它看起来并不是很棒,但可以完成工作。

List<DateTime> calculateDaysInterval(DateTime startDate, DateTime endDate) {
    List<DateTime> days = [];
    for (int i = 0; i <= endDate.difference(startDate).inDays; i++) {
      days.add(startDate.add(Duration(days: i)));
    }
    return days;
  }


如果大家有更好的方法,请告诉我。

如果日期处于具有夏令时的区域,则此方法可能会以意想不到的方式工作。例如,在PST时区中,以下代码:var date = new DateTime(2020, 3, 7, 23, 59); debugPrint(date.add(Duration(days: 1)).toString());将打印出 flutter: 2020-03-09 00:59:00.000,而var date = new DateTime(2020, 11, 1, 23, 59); debugPrint(date.add(Duration(days: 1)).toString());将打印出 flutter: 2020-11-02 23:59:00.000,这也许是你想要的,但通常并非如此。 - Ivan
只是为了澄清,由于夏令时将一天添加到第一个DateTime对象中,其中date.day == 7,因此由于时间变化,在第一个例子中结果为date.day == 9,而在第二个例子中即使添加了Duration(days: 1)date.day == 2 - Ivan

2
参考原始问题并尽量保持代码相似,导致代码冻结您的应用程序的原因是循环内的add函数不会就地运行,而是返回一个新的DateTime,如下所示:关于DateTime函数add的信息 因此,为了修复您的代码,您只需要将循环的最后部分更改为d = d.add(const Duration(days: 1))

1

这可能不是最高效的方法(事实上绝对不是高效的),但如果您必须确切地获取经过夏令时调整后的天数,那么这个方法可以使用。

DateTime startDate = new DateTime(2020, 3, 2);
DateTime endDate = new DateTime(2020, 3, 10);
List<DateTime> days = [];
DateTime tmp = DateTime(startDate.year, startDate.month, startDate.day, 12);
while(DateTime(tmp.year, tmp.month, tmp.day) != endDate){
  days.add(DateTime(tmp.year, tmp.month, tmp.day));
  tmp = tmp.add(new Duration(days: 1));
}

0

如果您在函数或类成员中实现了Iterable,仍然可以使用for循环或遍历日期范围(但您可以找到List对象),例如:

Class DateFormatter { 
  .....
  ....

   static Iterable<DateTime> EachDay(DateTimeRange dateRange) {
     List<DateTime> iterated = [];
    
     for (var day = dateRange.start.day; day <= dateRange.end.day; day++) {
       iterated.add(dateRange.start.add(Duration(days: day)));
     }
     return iterated;
   }
}

还有一个像这样的'for'循环:

for (DateTime cDate in DateFormatter.EachDay(dateRange)) {
  print(cDate.toString());
}

还有一种实现迭代器的方法,所有这些都对代码的占用空间影响很小。 使用迭代器,

var theITerator = DateFormatter.EachDay(dateRange).iterator;
    theITerator.moveNext();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接