3月31日4月1日的Dart / Flutter日期时间差异inDays错误

时间:2019-04-02 10:50:31

标签: dart flutter

我正在尝试从DatePicker中选择两个日期之间的天差 。除了一个日期:3月31日以外,此方法都可以正常运行。

两个DateTimes之间的天数差异到1天是错误的,其中一个日期是3月31日。我知道这是由于节电,3月是30.9天,而不是31天,因此我是猜测,错误。但是,除了手动检查日期是否等于3月31日并在结果中加上一天之外,还有谁知道如何解决此问题?

可以在Dart Pad中运行的两个非常简单的示例:

DateTime aprilFirst = DateTime(2019, 3, 30);
DateTime marchThirtyFirst = DateTime(2019, 3, 31);

print(aprilFirst.difference(marchThirtyFirst).inDays); => -1

DateTime marchThirty = DateTime(2019, 4, 1);
DateTime marchThirtyFirst = DateTime(2019, 3, 31);

print(marchThirty.difference(marchThirtyFirst).inDays); => 0

更新

DateTime aprilFirst = DateTime(2019, 4, 1);
print(aprilFirst.add(Duration(days: -1))); => 2019-03-30 23:00:00.000

这应该打印2019-03-31 23:00:00.000!

我尝试使用GünterZöchbauer的解决方案来制作DateTimes UTC,但结果完全相同:

DateTime aprilFirst = DateTime(2019, 4, 1).toUtc();
DateTime marchThirty = DateTime(2019, 3, 30).toUtc();
DateTime marchThirtyFirst = DateTime(2019, 3, 31).toUtc();

print(aprilFirst.difference(marchThirtyFirst).inHours); => 23
print(aprilFirst.difference(marchThirtyFirst).inDays); => 0
print(marchThirty.difference(marchThirtyFirst).inHours); => -24
print(aprilFirst.add(Duration(days: -1))); => 019-03-30 22:00:00.000Z

4 个答案:

答案 0 :(得分:2)

不进行日期比较或使用本地日期进行操作。首先将其转换为UTC。否则,夏令时和其他与DateTime有关的本地异常将导致各种令人惊讶的效果。

DateTime aprilFirst = DateTime(2019, 3, 30).toUtc();
DateTime marchThirtyFirst = DateTime(2019, 3, 31).toUtc();

print(aprilFirst.difference(marchThirtyFirst).inDays); => -1

如果结果为DateTime,则可以使用xxx.toLocal()

将其转换回

还有一个构造函数,它允许创建UTC DateTime而不是创建本地DateTime,然后转换为UTC。

答案 1 :(得分:1)

@GünterZöchbauer使我走上了正确的道路。 DateTime(...).toUTC()将无法进行差异计算。但是,使用DateTime.utc(...)构造函数可以达到目的!

DateTime aprilFirst = DateTime.utc(2019, 4, 1);
DateTime marchThirty = DateTime.utc(2019, 3, 30);
DateTime marchThirtyFirst = DateTime.utc(2019, 3, 31);

print(aprilFirst.difference(marchThirtyFirst).inHours); => 24
print(aprilFirst.difference(marchThirtyFirst).inDays); => 1
print(marchThirty.difference(marchThirtyFirst).inHours); => -24
print(aprilFirst.add(Duration(days: -1))); => 2019-03-31 00:00:00.000Z

答案 2 :(得分:1)

2021 基于答案

extension DateCalcs on DateTime {
  DateTime get dateOnlyUTC => DateTime.utc(this.year,this.month,this.day);
}

答案 3 :(得分:0)

尝试使用此软件包,Jiffy使用日期时间差的momentJs概念

您可以在此处https://github.com/moment/moment/pull/571看到

DateTime aprilFirst = DateTime(2019, 3, 30);
DateTime marchThirtyFirst = DateTime(2019, 3, 31);

Jiffy(aprilFirst).diff(marchThirtyFirst, "days"); // -1
// or
Jiffy([2019, 3, 30]).diff([2019, 3, 31], "days"); // -1

DateTime marchThirty = DateTime(2019, 4, 1);
DateTime marchThirtyFirst = DateTime(2019, 3, 31);

Jiffy(marchThirty).diff(marchThirtyFirst, "days"); // 1
Jiffy(marchThirty).diff(marchThirtyFirst, "hours"); // 24
Jiffy(marchThirty).diff(marchThirtyFirst, "months"); // 0