Flutter:找出两个日期之间的差异

Asy*_*yan 11 dart flutter

我目前有一个用户的个人资料页面,其中显示了他们的出生日期和其他详细信息。但是我打算通过计算今天的日期和从用户那里获得的出生日期之间的差值来找到他们生日前的日子。

用户的出生日期

用户DOB

这是使用intl包获得的今天的日期。

今天的日期

I/flutter ( 5557): 09-10-2018
Run Code Online (Sandbox Code Playgroud)

我现在面临的问题是,如何计算这两个日期的天数差异?

是否有任何特定的配方或包装可供我检查?

Mar*_*rcG 79

接受的答案是错误的。不要使用它。

这是对的:

int daysBetween(DateTime from, DateTime to) {
  from = DateTime(from.year, from.month, from.day);
  to = DateTime(to.year, to.month, to.day);
  return (to.difference(from).inHours / 24).round();
}
Run Code Online (Sandbox Code Playgroud)

测试:

DateTime date1 = DateTime.parse("2020-01-09 23:00:00.299871");
DateTime date2 = DateTime.parse("2020-01-10 00:00:00.299871");

expect(daysBetween(date1, date2), 1); // Works!
Run Code Online (Sandbox Code Playgroud)

解释为什么接受的答案是错误的:

只需运行这个:

int daysBetween_wrong1(DateTime date1, DateTime date2) {
  return date1.difference(date2).inDays;
}

DateTime date1 = DateTime.parse("2020-01-09 23:00:00.299871");
DateTime date2 = DateTime.parse("2020-01-10 00:00:00.299871");

// Should return 1, but returns 0.
expect(daysBetween_wrong1(date1, date2), 0);
Run Code Online (Sandbox Code Playgroud)

注意:由于夏令时的原因,即使标准化为 0:00,某一天与第二天之间也可能存在 23 小时的差异。这就是为什么以下也是不正确的:

// Fails, for example, when date2 was moved 1 hour before because of daylight savings.
int daysBetween_wrong2(DateTime date1, DateTime date2) {
  from = DateTime(date1.year, date1.month, date1.day);  
  to = DateTime(date2.year, date2.month, date2.day);
  return date2.difference(date1).inDays; 
}
Run Code Online (Sandbox Code Playgroud)

Rant:如果你问我的话,DartDateTime非常糟糕。它至少应该有基本的东西,比如daysBetween时区处理等。


更新:https://pub.dev/packages/time_machine声称是 Noda Time 的端口。如果是这种情况,并且它已正确移植(我还没有测试过),那么这就是您应该使用的日期/时间包。

  • 如果您的“daysBetween”函数使用“DateTime.utc”构造函数代替四舍五入,那么它会更清晰。UTC `DateTime` 对象不遵守 DST。 (2认同)

die*_*per 45

您可以使用differenceDateTime类提供的方法

 //the birthday's date
 final birthday = DateTime(1967, 10, 12);
 final date2 = DateTime.now();
 final difference = date2.difference(birthday).inDays;
Run Code Online (Sandbox Code Playgroud)

  • 有时此方法不符合预期 `DateTime.parse("2020-01-10 00:00:00.299871").difference(DateTime.parse("2020-01-09 23:00:00.299871")).inDays = 0`。 (8认同)
  • `difference` 计算两个时间点之间的毫秒或微秒,然后 `inDays` 返回该时间点内的整个“天”数(24 个整小时),并向下舍入。要计算两个日期之间的日历天数,日期应具有完全相同的小时/分钟/秒/毫秒/微秒(例如零)并且为 UTC 日 - 因为由于夏令时,某些当地时间日长为 23 或 25 小时。然后就可以了。 (4认同)
  • 这个答案是错误的。不要使用它。我发布了另一个答案,其中考虑了一天中的时间和夏令时。 (3认同)

jam*_*lin 11

天真地将一个DateTime与另一个相减DateTime.difference是微妙的错误。正如文档所解释DateTime

不同时区的两个日期之间的差异只是两个时间点之间的纳秒数。它不考虑日历天数。这意味着,如果中间有夏令时变化,当地时间两个午夜之间的时差可能小于 24 小时乘以它们之间的天数。

DateTime您可以使用UTC DateTime对象1在计算中忽略夏令时,而不是对计算的天数进行四舍五入,因为 UTC 不遵守 DST。

因此,要计算两个日期之间的天数差异,请忽略时间(也忽略夏令时调整和时区),构造DateTime具有相同日期并使用相同时间的新 UTC 对象:

/// Returns the number of calendar days between [later] and [earlier], ignoring
/// time of day.
///
/// Returns a positive number if [later] occurs after [earlier].
int differenceInCalendarDays(DateTime later, DateTime earlier) {
  // Normalize [DateTime] objects to UTC and to discard time information.
  later = DateTime.utc(later.year, later.month, later.day);
  earlier = DateTime.utc(earlier.year, earlier.month, earlier.day);

  return later.difference(earlier).inDays;
}
Run Code Online (Sandbox Code Playgroud)

更新

我添加了一个calendarDaysTill扩展方法package:basics可以做到这一点。


1请注意,将本地对象转换DateTime为 UTC.toUtc()没有帮助;dateTimedateTime.toUtc()都代表同一时刻,因此dateTime1.difference(dateTime2)dateTime1.toUtc().difference(dateTime.toUtc())会返回相同的Duration


Rud*_*wal 9

使用 DateTime 类找出两个日期之间的差异。

DateTime dateTimeCreatedAt = DateTime.parse('2019-9-11'); 
DateTime dateTimeNow = DateTime.now();
final differenceInDays = dateTimeNow.difference(dateTimeCreatedAt).inDays;
print('$differenceInDays');
Run Code Online (Sandbox Code Playgroud)

或者

您可以使用jiffy。Jiffy 是一个受 momentjs 启发的 date dart 包,用于解析、操作和格式化日期。

示例: 1. 相对时间

Jiffy("2011-10-31", "yyyy-MM-dd").fromNow(); // 8 years ago
Jiffy("2012-06-20").fromNow(); // 7 years ago

var jiffy1 = Jiffy()
    ..startOf(Units.DAY);
jiffy1.fromNow(); // 19 hours ago

var jiffy2 = Jiffy()
    ..endOf(Units.DAY);
jiffy2.fromNow(); // in 5 hours

var jiffy3 = Jiffy()
    ..startOf(Units.HOUR);
jiffy3.fromNow(); 
Run Code Online (Sandbox Code Playgroud)

2. 日期操作:

var jiffy1 = Jiffy()
      ..add(duration: Duration(days: 1));
jiffy1.yMMMMd; // October 20, 2019

var jiffy2 = Jiffy()
    ..subtract(days: 1);
jiffy2.yMMMMd; // October 18, 2019

//  You can chain methods by using Dart method cascading
var jiffy3 = Jiffy()
     ..add(hours: 3, days: 1)
     ..subtract(minutes: 30, months: 1);
jiffy3.yMMMMEEEEdjm; // Friday, September 20, 2019 9:50 PM

var jiffy4 = Jiffy()
    ..add(duration: Duration(days: 1, hours: 3))
    ..subtract(duration: Duration(minutes: 30));
jiffy4.format("dd/MM/yyy"); // 20/10/2019


// Months and year are added in respect to how many 
// days there are in a months and if is a year is a leap year
Jiffy("2010/1/31", "yyyy-MM-dd"); // This is January 31
Jiffy([2010, 1, 31]).add(months: 1); // This is February 28
Run Code Online (Sandbox Code Playgroud)


non*_*hto 7

您可以使用 Datetime 类来查找两年之间的差异,而无需使用 intl 来格式化日期。

DateTime dob = DateTime.parse('1967-10-12');
Duration dur =  DateTime.now().difference(dob);
String differenceInYears = (dur.inDays/365).floor().toString();
return new Text(differenceInYears + ' years');
Run Code Online (Sandbox Code Playgroud)

  • 不处理闰年,因此关闭日期不正确 (18认同)

Abd*_*han 7

如果有人想找出秒、分钟、小时和天形式的区别。然后这是我的方法。

static String calculateTimeDifferenceBetween(
      {@required DateTime startDate, @required DateTime endDate}) {
    int seconds = endDate.difference(startDate).inSeconds;
    if (seconds < 60)
      return '$seconds second';
    else if (seconds >= 60 && seconds < 3600)
      return '${startDate.difference(endDate).inMinutes.abs()} minute';
    else if (seconds >= 3600 && seconds < 86400)
      return '${startDate.difference(endDate).inHours} hour';
    else
      return '${startDate.difference(endDate).inDays} day';
  }
Run Code Online (Sandbox Code Playgroud)


小智 6

void main() {
DateTime dt1 = DateTime.parse("2021-12-23 11:47:00");
DateTime dt2 = DateTime.parse("2018-09-12 10:57:00");

Duration diff = dt1.difference(dt2);

print(diff.inDays);
//output (in days): 1198

print(diff.inHours);
     
//output (in hours): 28752

}
Run Code Online (Sandbox Code Playgroud)