周列表未能给出正确的输出。

huangapple go评论74阅读模式
英文:

Week list not give me correct out put

问题

以下是您要翻译的代码部分:

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class WeekList extends StatefulWidget {
  const WeekList({super.key});

  @override
  State<WeekList> createState() => _WeekListState();
}

class _WeekListState extends State<WeekList> {
  @override
  Widget build(BuildContext context) {
    DateTime currentDate = DateTime.now();
    DateTime startOfWeek = getStartOfWeek(currentDate);

    List<String> weekDateRange = generateWeekDateRange(startOfWeek, 5); // 5 weeks display karein

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Date Range List'),
        ),
        body: ListView.builder(
          itemCount: weekDateRange.length,
          itemBuilder: (context, index) {
            String dateRange = weekDateRange[index];
            bool isSelected = isDateRangeSelected(dateRange, currentDate);
            return ListTile(
              title: Text(
                dateRange,
                style: TextStyle(
                  fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

DateTime getStartOfWeek(DateTime date) {
  return date.subtract(Duration(days: date.weekday - 1));
}

List<String> generateWeekDateRange(DateTime startOfWeek, int numberOfWeeks) {
  List<String> weekList = [];
  for (int i = 0; i < numberOfWeeks; i++) {
    DateTime endDate = startOfWeek.add(const Duration(days: 6));

    if (endDate.day <= 7) {
      // Check if endDate is on or before the 7th day of the month
      DateTime nextMonth = DateTime(startOfWeek.year, startOfWeek.month + 1, 1);
      endDate = nextMonth.subtract(const Duration(days: 1));
    }

    if (endDate.isAfter(DateTime(startOfWeek.year, startOfWeek.month, startOfWeek.day + 6))) {
      // Check if endDate is in the next month
      endDate = DateTime(startOfWeek.year, startOfWeek.month, startOfWeek.day + 6);
    }

    String formattedDateRange =
        '${DateFormat('dd/MM').format(startOfWeek)} - ${DateFormat('dd/MM').format(endDate)}';
    weekList.add(formattedDateRange);

    // Move the startOfWeek to the next week
    startOfWeek = endDate.add(const Duration(days: 1));
  }
  return weekList;
}

bool isDateRangeSelected(String dateRange, DateTime currentDate) {
  List<String> parts = dateRange.split(' - ');
  DateTime startDate = DateFormat('dd/MM').parse(parts[0]);
  DateTime endDate = DateFormat('dd/MM').parse(parts[1]);
  return currentDate.isAfter(startDate) && currentDate.isBefore(endDate.add(const Duration(days: 1)));
}

请注意,我已将代码部分翻译成中文,但您提供的代码中没有明确要求的日期范围输出部分。如果您需要帮助将日期范围输出部分翻译成您想要的格式,请提供相关代码并告诉我您想要的格式,我将尽力帮助您完成翻译。

英文:

My code :

  1. Select 24 date

  2. they print 31/07 - 31/07

  3. not print like this 31/07 - 06/08

import &#39;package:flutter/material.dart&#39;;
import &#39;package:intl/intl.dart&#39;;
class WeekList extends StatefulWidget {
const WeekList({super.key});
@override
State&lt;WeekList&gt; createState() =&gt; _WeekListState();
}
class _WeekListState extends State&lt;WeekList&gt; {
@override
Widget build(BuildContext context) {
DateTime currentDate = DateTime.now();
DateTime startOfWeek = getStartOfWeek(currentDate);
List&lt;String&gt; weekDateRange = generateWeekDateRange(startOfWeek, 5); // 5 weeks display karein
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text(&#39;Date Range List&#39;),
),
body: ListView.builder(
itemCount: weekDateRange.length,
itemBuilder: (context, index) {
String dateRange = weekDateRange[index];
bool isSelected = isDateRangeSelected(dateRange, currentDate);
return ListTile(
title: Text(
dateRange,
style: TextStyle(
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
),
),
);
},
),
),
);
}
}
DateTime getStartOfWeek(DateTime date) {
return date.subtract(Duration(days: date.weekday - 1));
}
List&lt;String&gt; generateWeekDateRange(DateTime startOfWeek, int numberOfWeeks) {
List&lt;String&gt; weekList = [];
for (int i = 0; i &lt; numberOfWeeks; i++) {
DateTime endDate = startOfWeek.add(const Duration(days: 6));
if (endDate.day &lt;= 7) {
// Check if endDate is on or before the 7th day of the month
DateTime nextMonth = DateTime(startOfWeek.year, startOfWeek.month + 1, 1);
endDate = nextMonth.subtract(const Duration(days: 1));
}
if (endDate.isAfter(DateTime(startOfWeek.year, startOfWeek.month, startOfWeek.day + 6))) {
// Check if endDate is in the next month
endDate = DateTime(startOfWeek.year, startOfWeek.month, startOfWeek.day + 6);
}
String formattedDateRange =
&#39;${DateFormat(&#39;dd/MM&#39;).format(startOfWeek)} - ${DateFormat(&#39;dd/MM&#39;).format(endDate)}&#39;;
weekList.add(formattedDateRange);
// Move the startOfWeek to the next week
startOfWeek = endDate.add(const Duration(days: 1));
}
return weekList;
}
bool isDateRangeSelected(String dateRange, DateTime currentDate) {
List&lt;String&gt; parts = dateRange.split(&#39; - &#39;);
DateTime startDate = DateFormat(&#39;dd/MM&#39;).parse(parts[0]);
DateTime endDate = DateFormat(&#39;dd/MM&#39;).parse(parts[1]);
return currentDate.isAfter(startDate) &amp;&amp; currentDate.isBefore(endDate.add(const Duration(days: 1)));
}

Current output:

I/flutter (30371): 01/08 - 07/08
I/flutter (30371): 08/08 - 14/08
I/flutter (30371): 15/08 - 21/08
I/flutter (30371): 24/07 - 30/07
I/flutter (30371): 31/07 - 31/07

i want to print like this:

24/07 - 30-07  
31/07 -  06/08  
07/08 - 13/08  
14/08 - 20/08

答案1

得分: 1

You most likely hit into the issue of handling daylight summer time (DST). DateTime in Dart are default your local timezone which often have the concept of DST. When you use add/sub on DateTime, you provide a Duration object which converts all units into e.g. milliseconds. So when adding days, it will convert each day to 24 hour and so on.

但因为夏令时允许一天有时长为25小时和23小时的情况,所以在Dart中添加天数经常会出现这些问题。

解决方案通常是使用UTC作为时区,因为这是一个没有夏令时的固定时区。所以当你想要当前时间时,使用 DateTime.timestamp() 来获取 DateTime 的UTC版本。而当你创建新的 DateTime 对象时,确保使用 DateTime.utc() 构造函数而不是 DateTime

更多关于这方面的信息,请查看 DateTime 的文档:https://api.dart.dev/stable/3.0.6/dart-core/DateTime-class.html

我还注意到你的 generateWeekDateRange 方法比所需的输出要复杂得多。

以下是我认为可以修复你的代码的示例,我还简化了 generateWeekDateRange。我自己不使用Flutter,所以我没有测试过它:

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class WeekList extends StatefulWidget {
  const WeekList({super.key});

  @override
  State<WeekList> createState() => _WeekListState();
}

class _WeekListState extends State<WeekList> {
  @override
  Widget build(BuildContext context) {
    DateTime currentDate = DateTime.now().toUtc();
    DateTime startOfWeek = getStartOfWeek(currentDate);

    List<String> weekDateRange =
        generateWeekDateRange(startOfWeek, 5); // 5 weeks display karein

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Date Range List'),
        ),
        body: ListView.builder(
          itemCount: weekDateRange.length,
          itemBuilder: (context, index) {
            String dateRange = weekDateRange[index];
            bool isSelected = isDateRangeSelected(dateRange, currentDate);
            return ListTile(
              title: Text(
                dateRange,
                style: TextStyle(
                  fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

DateTime getStartOfWeek(DateTime date) {
  return date.subtract(Duration(days: date.weekday - 1));
}

List<String> generateWeekDateRange(DateTime startOfWeek, int numberOfWeeks) {
  List<String> weekList = [];
  for (int i = 0; i < numberOfWeeks; i++) {
    DateTime endDate = startOfWeek.add(const Duration(days: 6));

    String formattedDateRange =
        '${DateFormat('dd/MM').format(startOfWeek)} - ${DateFormat('dd/MM').format(endDate)}';
    weekList.add(formattedDateRange);

    // Move the startOfWeek to the next week
    startOfWeek = endDate.add(const Duration(days: 1));
  }
  return weekList;
}

bool isDateRangeSelected(String dateRange, DateTime currentDate) {
  List<String> parts = dateRange.split(' - ');
  DateTime startDate = DateFormat('dd/MM').parseUtc(parts[0]);
  DateTime endDate = DateFormat('dd/MM').parseUtc(parts[1]);
  return currentDate.isAfter(startDate) &&
      currentDate.isBefore(endDate.add(const Duration(days: 1)));
}

希望这对你有所帮助!

英文:

You most likely hit into the issue of handling daylight summer time (DST). DateTime in Dart are default your local timezone which often have the concept of DST. When you use add/sub on DateTime, you provide a Duration object which converts all units into e.g. milliseconds. So when adding days, it will convert each day to 24 hour and so on.

But because DST allows days to be sometimes 25 hours and 23 hours long, the adding of days in Dart does often give these problems.

The solution is often to use UTC as timezone instead since this is a fixed timezone without DST. So when you want current time, use DateTime.timestamp() instead to get a UTC version of DateTime. And when you create new DateTime objects, make sure to use the DateTime.utc() constructor instead of DateTime.

Read more about this in the documentation of DateTime: https://api.dart.dev/stable/3.0.6/dart-core/DateTime-class.html

I can also see your generateWeekDateRange method are a lot more complicated than needed for the output you want.

Example of how I think your code could be fixed where I have also simplified generateWeekDateRange. I don't use Flutter myself so I have not tested it:

import &#39;package:flutter/material.dart&#39;;
import &#39;package:intl/intl.dart&#39;;

class WeekList extends StatefulWidget {
  const WeekList({super.key});

  @override
  State&lt;WeekList&gt; createState() =&gt; _WeekListState();
}

class _WeekListState extends State&lt;WeekList&gt; {
  @override
  Widget build(BuildContext context) {
    DateTime currentDate = DateTime.timestamp();
    DateTime startOfWeek = getStartOfWeek(currentDate);

    List&lt;String&gt; weekDateRange =
        generateWeekDateRange(startOfWeek, 5); // 5 weeks display karein

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text(&#39;Date Range List&#39;),
        ),
        body: ListView.builder(
          itemCount: weekDateRange.length,
          itemBuilder: (context, index) {
            String dateRange = weekDateRange[index];
            bool isSelected = isDateRangeSelected(dateRange, currentDate);
            return ListTile(
              title: Text(
                dateRange,
                style: TextStyle(
                  fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

DateTime getStartOfWeek(DateTime date) {
  return date.subtract(Duration(days: date.weekday - 1));
}

List&lt;String&gt; generateWeekDateRange(DateTime startOfWeek, int numberOfWeeks) {
  List&lt;String&gt; weekList = [];
  for (int i = 0; i &lt; numberOfWeeks; i++) {
    DateTime endDate = startOfWeek.add(const Duration(days: 6));

    String formattedDateRange =
        &#39;${DateFormat(&#39;dd/MM&#39;).format(startOfWeek)} - ${DateFormat(&#39;dd/MM&#39;).format(endDate)}&#39;;
    weekList.add(formattedDateRange);

    // Move the startOfWeek to the next week
    startOfWeek = endDate.add(const Duration(days: 1));
  }
  return weekList;
}

bool isDateRangeSelected(String dateRange, DateTime currentDate) {
  List&lt;String&gt; parts = dateRange.split(&#39; - &#39;);
  DateTime startDate = DateFormat(&#39;dd/MM&#39;).parseUtc(parts[0]);
  DateTime endDate = DateFormat(&#39;dd/MM&#39;).parseUtc(parts[1]);
  return currentDate.isAfter(startDate) &amp;&amp;
      currentDate.isBefore(endDate.add(const Duration(days: 1)));
}

huangapple
  • 本文由 发表于 2023年7月24日 15:28:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76752245.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定