How to get a list of each week in a time range with Dart?
Solution 1
As Stefano wrote, it's good to create a class with a structure to be able to achieve your goals. My suggestion is a little more simple since I just wrote a method you could use. You could even create an extension on the DateTime class and use that in the future, or implement it in a static class, or add it to an instance class. Here is the complete example that works on DartPad:
void main() {
var weeks = getWeeksForRange(DateTime.utc(2020,08,12), DateTime.utc(2020,10,12));
print(weeks);
}
List<List<DateTime>> getWeeksForRange(DateTime start, DateTime end) {
var result = List<List<DateTime>>();
var date = start;
var week = List<DateTime>();
while(date.difference(end).inDays <= 0) {
// start new week on Monday
if (date.weekday == 1 && week.length > 0) {
print('Date $date is a Monday');
result.add(week);
week = List<DateTime>();
}
week.add(date);
date = date.add(const Duration(days: 1));
}
result.add(week);
return result;
}
This method can take any two dates and create a list of lists (weeks) of DateTime
objects. Since in the result you will have many DateTime results, you can then map them however you want since they will have all information about its date, year, weekday and will keep the formatting feature.
Solution 2
One first step could be to create a Class
according to your needs:
class Day {
final DateTime dateTime;
Day({
this.dateTime,
});
String get day => DateFormat('EEEE').format(dateTime);
String get date => DateFormat('yMMMd').format(dateTime);
Map<String, String> toMap() => {'dayName': day, 'date': date};
}
We can construct the Class
above just with a DateTime
and from it, we can derive the day
and date
using DateFormat
in the getters:
String get day => DateFormat('EEEE').format(dateTime); // returns "Friday" for example
String get date => DateFormat('yMMMd').format(dateTime); // returns "Jun 13, 2021" for example
The toMap()
method allows use to easily convert the Class
to a Map<String, String>
:
Map<String, String> toMap() => {'dayName': day, 'date': date};
We now need to store the Day
s in a List<Day>
:
List<Day> days = [];
By iterating from the starting DateTime
to the ending DateTime
:
DateTime now = DateTime.now(); // as an example
DateTime start = now;
DateTime after = now.add(Duration(days: 180));
DateTime iterator = start;
List<Day> days = [];
while (iterator.isBefore(after)) {
days.add(Day(dateTime: iterator));
iterator = iterator.add(Duration(days: 1));
}
A full source code for the scenario outlined can be found below:
import 'package:intl/intl.dart';
class Day {
final DateTime dateTime;
Day({
this.dateTime,
});
String get day => DateFormat('EEEE').format(dateTime);
String get date => DateFormat('yMMMd').format(dateTime);
String toString() =>
'\t{\n\t\t"dayName": "$day",\n\t\t"date": "$date"\n\t}\n';
Map<String, String> toMap() => {'dayName': day, 'date': date};
}
void main() {
DateTime now = DateTime.now();
DateTime start = now;
DateTime after = now.add(Duration(days: 180));
DateTime iterator = start;
List<Day> days = [];
while (iterator.isBefore(after)) {
days.add(Day(dateTime: iterator));
iterator = iterator.add(Duration(days: 1));
}
print(days);
}
If you'd like to group the Day
s by week, we'll then need a multi-dimensional List
:
void main() {
DateTime now = DateTime.now();
DateTime start = now;
DateTime after = now.add(Duration(days: 180));
DateTime iterator = start;
List<List<Day>> days = [[]]; // multi-dimensional List
int i = 0;
while (iterator.isBefore(after)) {
if (days[i].isEmpty) days.add([]); // init of the week List
days[i].add(Day(dateTime: iterator));
if (iterator.weekday == 7) i++; // new week
iterator = iterator.add(Duration(days: 1));
}
print(days);
}
F.SO7
Updated on December 07, 2022Comments
-
F.SO7 11 months
I am trying to build a weeks-timeline in my Flutter app.
I am trying to generate a list of all of the weeks in a given time range (for example December 2020 - December 2021).
Each week will be a list by itself, which will hold the days. Something like this:
[ [ { dayName: 'Sunday', date: 'December 13 2020', }, { dayName: 'Monday', date: 'December 14 2020', }, { dayName: 'Tuesday', date: 'December 15 2020', }, { dayName: 'Wednesday', date: 'December 16 2020', }, { dayName: 'Thursday', date: 'December 17 2020', }, { dayName: 'Friday', date: 'December 18 2020', }, { dayName: 'Saturday', date: 'December 19 2020', }, ], //Another Week Array //Another Week Array //Etc ]
Does anyone know how can I achieve this type of data in Dart and Flutter?
Thank you!
-
Mohammad Mirshahbazi almost 3 yearsCan you explain more, that what do you want exactly ?
-
-
F.SO7 almost 3 yearsThank you very much. But for some reason your code outputs only 6 items (days) per week. Why isn't it 7?
-
kovalyovi almost 3 years@F.SO7 thank you for noting! I fixed it and edited my answer. It was a small issue. Does that answer your question?
-
kovalyovi almost 3 yearsHey, @F.SO7, check out my update. I changed it a little since using DayTime for November 01, 2022 creates a bug since there is a transition to the daylight savings. To avoid that instead of using
DateTime
object I usedDateTime.utc
. That solved the issue. I also changedhours: 24
todays: 1
for a better clarity.