You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter/Dart中基于DateTime和TimeOfDay对列表项排序

问题根源

你当前的写法连续执行3次独立的sort排序,后一次排序会完全覆盖前一次的排序逻辑,仅保留最后一次的排序结果。比如你先按日期排序完成后,再按小时排序时,会忽略日期差异,把不同日期但小时相同的任务混排,最终结果自然不符合预期。

最优实现方案

方案1:合并为完整DateTime比较(最简洁)

直接将任务的日期和时间拼接为完整的DateTime对象,一次比较即可得出结果,代码可读性高且不易出错:

_tasks.sort((a, b) {
  // 拼接a的完整时间
  final aDateTime = DateTime(
    a.date!.year, 
    a.date!.month, 
    a.date!.day, 
    a.time!.hour, 
    a.time!.minute
  );
  // 拼接b的完整时间
  final bDateTime = DateTime(
    b.date!.year, 
    b.date!.month, 
    b.date!.day, 
    b.time!.hour, 
    b.time!.minute
  );
  // 升序排列,如需降序改为 bDateTime.compareTo(aDateTime)
  return aDateTime.compareTo(bDateTime);
});

方案2:分层优先级比较

如果不需要拼接完整时间,可以在同一个排序回调内按优先级分层比较,效果和方案1完全一致:

_tasks.sort((a, b) {
  // 优先级1:先比较日期
  final dateDiff = a.date!.compareTo(b.date!);
  if (dateDiff != 0) return dateDiff;
  // 优先级2:日期相同比较小时
  final hourDiff = a.time!.hour.compareTo(b.time!.hour);
  if (hourDiff != 0) return hourDiff;
  // 优先级3:小时相同比较分钟
  return a.time!.minute.compareTo(b.time!.minute);
});

可选拓展:空值&状态兼容

如果你的业务中存在date或time为空的场景,或者需要把未完成任务排到前面,可以加上对应判断逻辑:

_tasks.sort((a, b) {
  // 优先级0:未完成任务排前面
  if (a.isFinished != b.isFinished) {
    return a.isFinished ? 1 : -1;
  }
  // 空日期处理:空值排到列表末尾
  if (a.date == null && b.date == null) return 0;
  if (a.date == null) return 1;
  if (b.date == null) return -1;
  // 空时间处理:同日期下空时间排末尾
  if (a.time == null && b.time == null) return 0;
  if (a.time == null) return 1;
  if (b.time == null) return -1;
  // 正常比较时间
  final aDateTime = DateTime(a.date!.year, a.date!.month, a.date!.day, a.time!.hour, a.time!.minute);
  final bDateTime = DateTime(b.date!.year, b.date!.month, b.date!.day, b.time!.hour, b.time!.minute);
  return aDateTime.compareTo(bDateTime);
});

内容的提问来源于stack exchange,提问作者MhdBasilE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 08:09:01