Return all dates between two dates as a list in flutter date range picker
Asked Answered
C

4

7

I got only two dates form flutter date_range_picker but I want a list of date between two selected dates. Thanks for your answers

Calamine answered 22/4, 2020 at 10:21 Comment(1)
Could you please show us the code you're using currently? (Show us only the relevant part.)Filterable
F
21

Try the following :

List<DateTime> getDaysInBetween(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;
  }
Furnishings answered 22/4, 2020 at 10:51 Comment(3)
as @henry2man suggested below, this solution falls over on some edge cases.Shivery
@Shivery what edge cases?Motte
@Motte it fails during the switch from the summer time to winter time in autumn and springShivery
S
10

There is a problem with the accepted solution. The code will run fine most of the time but it will fail because this doesn't considers Daylight saving time (DST) / Daylight time / Summer Time (https://en.wikipedia.org/wiki/Daylight_saving_time).

As a result, for example it will generate the following sequence (notice the gap):

2020-10-24 00:00:00.000
2020-10-25 00:00:00.000
2020-10-25 23:00:00.000 # Mind the Gap :)
2020-10-26 23:00:00.000

Here it is an alternative solution that will work better, I think.

List<DateTime> getDaysInBeteween(DateTime startDate, DateTime endDate) {
    List<DateTime> days = [];
    for (int i = 0; i <= endDate.difference(startDate).inDays; i++) {
      days.add(
        DateTime(
          startDate.year, 
          startDate.month, 
          // In Dart you can set more than. 30 days, DateTime will do the trick
          startDate.day + i)
      );
    }
    return days;
}
Stoup answered 30/10, 2020 at 9:36 Comment(0)
R
3

Always use UTC to avoid issues like DST when working with dates such as addition or subtraction and then convert them back to local time.

Also, adding days manually like day + 1 could cause issues if both the start and end dates are not of the same month.

So to avoid all that do it like this:-

Case 1 - Get days in between including start and end Date:-

List<DateTime> getDaysInBetweenIncludingStartEndDate(
    {required DateTime startDateTime, required DateTime endDateTime}) {
  // Converting dates provided to UTC
  // So that all things like DST don't affect subtraction and addition on dates
  DateTime startDateInUTC =
      DateTime.utc(startDateTime.year, startDateTime.month, startDateTime.day);
  DateTime endDateInUTC =
      DateTime.utc(endDateTime.year, endDateTime.month, endDateTime.day);

  // Created a list to hold all dates
  List<DateTime> daysInFormat = [];

  // Starting a loop with the initial value as the Start Date
  // With an increment of 1 day on each loop
  // With condition current value of loop is smaller than or same as end date
  for (DateTime i = startDateInUTC;
      i.isBefore(endDateInUTC) || i.isAtSameMomentAs(endDateInUTC);
      i = i.add(const Duration(days: 1))) {
    // Converting back UTC date to Local date if it was local before
    // Or keeping in UTC format if it was UTC

    if (startDateTime.isUtc) {
      daysInFormat.add(i);
    } else {
      daysInFormat.add(DateTime(i.year, i.month, i.day));
    }
  }
  return daysInFormat;
}

Case 2 - Get days in between excluding start and end Date:-

List<DateTime> getDaysInBetweenExcludingStartEndDate(
    {required DateTime startDateTime, required DateTime endDateTime}) {

  // Converting dates provided to UTC
  // So that all things like DST don't affect subtraction and addition on dates
  DateTime startDateInUTC =
      DateTime.utc(startDateTime.year, startDateTime.month, startDateTime.day);
  DateTime endDateInUTC =
      DateTime.utc(endDateTime.year, endDateTime.month, endDateTime.day);

  // Created a list to hold all dates
  List<DateTime> daysInFormat= [];
  
  // Starting a loop with the initial value as the next day of the Start Date
  // With an increment of 1 day on each loop
  // With condition current value of loop is smaller than end date
  for (DateTime i = startDateInUTC.add(const Duration(days: 1));
      i.isBefore(endDateInUTC);
      i = i.add(const Duration(days: 1))) {

    // Converting back UTC date to Local date if it was local before
    // Or keeping in UTC format if it was UTC

    if (startDateTime.isUtc) {
      daysInFormat.add(i);
    } else {
      daysInFormat.add(DateTime(i.year, i.month, i.day));
    }
  }
  return daysInFormat;
}
Reject answered 29/7, 2022 at 12:10 Comment(0)
B
0

I always do like this:

final today = DateTime.now();
final monthAgo = DateTime(today.year, today.month - 1, today.day);

final List<DateTime> days = [];
for (int i = 0; i <= today.difference(monthAgo).inDays; i++) {
  days.add(monthAgo.add(Duration(days: i)));
}
Boice answered 1/6, 2020 at 12:22 Comment(1)
as @Stoup suggested below, this solution falls over on some edge cases.Shivery

© 2022 - 2024 — McMap. All rights reserved.