【问题标题】:Dart Lang: Strange result adding 7 days. Sometimes it doesn't compute wellDart Lang:奇怪的结果增加了 7 天。有时计算不好
【发布时间】:2021-09-13 19:14:14
【问题描述】:

给定一个日期,假设是星期一,我希望如果加上 7 天,我会得到一个新的星期一。

有时就是这样,在某些情况下,它增加了一点,我得到了一个星期天。 我可以继续增加 7 天,然后得到星期天,直到我得到一个新的星期一。

我怎样才能制定一个精确的周期,让我在一周的同一天返回。

这里我将代码留在 Dart 中。链接到dartpad

void main() {
  var date = DateTime(2020, 10, 20);
  var weekday = date.weekday;
  var endDate = DateTime(2021, 4, 8);
  while (endDate.difference(date).inDays > 0) {
    assert(date.weekday == weekday);
    print('$date ${date.weekday} $weekday');
    date = date.add(Duration(days: 7));
  }
  print('end');
}

结果是

2020-10-20 00:00:00.000 2 2
2020-10-26 23:00:00.000 1 2
2020-11-02 23:00:00.000 1 2
2020-11-09 23:00:00.000 1 2
2020-11-16 23:00:00.000 1 2
2020-11-23 23:00:00.000 1 2
2020-11-30 23:00:00.000 1 2
2020-12-07 23:00:00.000 1 2
2020-12-14 23:00:00.000 1 2
2020-12-21 23:00:00.000 1 2
2020-12-28 23:00:00.000 1 2
2021-01-04 23:00:00.000 1 2
2021-01-11 23:00:00.000 1 2
2021-01-18 23:00:00.000 1 2
2021-01-25 23:00:00.000 1 2
2021-02-01 23:00:00.000 1 2
2021-02-08 23:00:00.000 1 2
2021-02-15 23:00:00.000 1 2
2021-02-22 23:00:00.000 1 2
2021-03-01 23:00:00.000 1 2
2021-03-08 23:00:00.000 1 2
2021-03-15 23:00:00.000 1 2
2021-03-22 23:00:00.000 1 2
2021-03-30 00:00:00.000 2 2
2021-04-06 00:00:00.000 2 2
end

【问题讨论】:

  • 它来自夏令时。请注意 10 月下旬和 3 月前后时间相差一小时。
  • 正确。您没有添加七个日历日。您正在添加 7 个时钟日,也就是。 7 * 24 小时。当时区因夏令时而改变时,这意味着您将无法获得与以前相同的时钟时间。

标签: datetime dart weekday


【解决方案1】:

如 cmets 中所述,Duration(days: 7) 表示 7 * 24 小时。 (Duration 内部只是一个表示微秒数的整数。)如果您的本地时区由于夏令时而更改,则将“1 天”(24 小时)添加到本地 DateTime 对象可能会导致 @ 987654325@ 对象,如果夏令时在该时间间隔内开始或结束,则本地时间与原始时间不同。

如DateTime documentation中提到的:

不同时区的两个日期之间的差异只是两个时间点之间的纳秒数。它不考虑日历天数。这意味着当地时间的两个午夜之间的差异可能小于 24 小时乘以它们之间的天数,如果两者之间有夏令时变化。如果上面的差异是使用澳大利亚当地时间计算的,那么差异是7415天和23小时,这只是inDays报告的7415天。

如果您只想添加日历天而不影响时间,该怎么办?您可以使用 UTC 而不是您的本地时区,但如果您想向用户显示时间,这可能不友好。或者,您可以提供自己的函数来添加多个日历日并复制原始时间:

extension DateTimeAddCalendarDays on DateTime {
  DateTime addCalendarDays(int numDays) => copyWith(day: day + numDays);

  DateTime copyWith({
    int? year,
    int? month,
    int? day,
    int? hour,
    int? minute,
    int? second,
    int? millisecond,
    int? microsecond,
  }) {
    if (this.isUtc) {
      return DateTime.utc(
        year ?? this.year,
        month ?? this.month,
        day ?? this.day,
        hour ?? this.hour,
        minute ?? this.minute,
        second ?? this.second,
        millisecond ?? this.millisecond,
        microsecond ?? this.microsecond,
      );
    } else {
      return DateTime(
        year ?? this.year,
        month ?? this.month,
        day ?? this.day,
        hour ?? this.hour,
        minute ?? this.minute,
        second ?? this.second,
        millisecond ?? this.millisecond,
        microsecond ?? this.microsecond,
      );
    }
  }
}

然后将date.add(Duration(days: 7)) 替换为date.addCalendarDays(7)。

【讨论】:

  • 非常感谢。
  • @Santii 如果我的回答对您有帮助,请点赞和/或接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-05
  • 2017-03-11
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多