Я пытаюсь построить недельный график в своем приложении Flutter.
Я пытаюсь создать список всех недель в заданном временном диапазоне (например, с декабря 2020 г. по декабрь 2021 г.).
Каждая неделя будет сама по себе списком, который будет содержать дни. Что-то вроде этого:
[
[
{
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
]
Кто-нибудь знает, как я могу получить этот тип данных в Dart и Flutter?
Спасибо!
Одним из первых шагов может быть создание Class
в соответствии с вашими потребностями:
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};
}
Мы можем построить Class
выше только с DateTime
и из него мы можем получить day
и date
, используя DateFormat
в геттерах:
String get day => DateFormat('EEEE').format(dateTime); // returns "Friday" for example
String get date => DateFormat('yMMMd').format(dateTime); // returns "Jun 13, 2021" for example
Метод toMap()
позволяет легко преобразовать Class
в Map<String, String>
:
Map<String, String> toMap() => {'dayName': day, 'date': date};
Теперь нам нужно сохранить Day
s в List<Day>
:
List<Day> days = [];
Итерируя от начала DateTime
до окончания 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));
}
Полный исходный код описанного сценария можно найти ниже:
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);
}
Если вы хотите сгруппировать Day
по неделям, нам понадобится многомерный 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);
}
Как писал Стефано, хорошо создать класс со структурой, позволяющей достигать поставленных целей. Мое предложение немного проще, так как я только что написал метод, который вы могли бы использовать. Вы даже можете создать расширение класса DateTime и использовать его в будущем, или реализовать его в статическом классе, или добавить его в класс экземпляра. Вот полный пример, который работает на 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;
}
Этот метод может принимать любые две даты и создавать список списков (недель) DateTime
объектов. Поскольку в результате у вас будет много результатов DateTime, вы можете сопоставить их, как хотите, поскольку они будут иметь всю информацию о дате, году, дне недели и сохранят функцию форматирования.
Большое спасибо. Но по какой-то причине ваш код выводит только 6 элементов (дней) в неделю. Почему не 7?
@ F.SO7, спасибо за внимание! Я исправил это и отредактировал свой ответ. Это была небольшая проблема. Это отвечает на ваш вопрос?
Привет, @F.SO7, посмотри мое обновление. Я немного изменил его, так как использование DayTime для 01 ноября 2022 года создает ошибку, так как есть переход на летнее время. Чтобы избежать этого, вместо объекта DateTime
я использовал DateTime.utc
. Это решило проблему. Я также изменил hours: 24
на days: 1
для большей ясности.
Можете ли вы объяснить больше, что именно вы хотите?