Flutter:查找两个日期之间的天数

Flutter: Find the number of days between two dates

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

用户的出生日期

这是使用intl package得到的今天的日期。

今天的日期

I/flutter ( 5557): 09-10-2018

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

是否有任何特定的配方或套餐可供我查看?

您可以使用DateTimeclass

提供的difference方法
 //the birthday's date
 final birthday = DateTime(1967, 10, 12);
 final date2 = DateTime.now();
 final difference = date2.difference(birthday).inDays;

更新

由于你们中的许多人报告此解决方案存在错误,为了避免更多错误,我将在此处添加@MarcG 提出的正确解决方案,所有功劳都归功于他。

  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();
  }

   //the birthday's date
   final birthday = DateTime(1967, 10, 12);
   final date2 = DateTime.now();
   final difference = daysBetween(birthday, date2);

这是完整解释的原始答案:

您可以使用日期时间 class 查找两年之间的差异,而无需使用 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');

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

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

您可以使用 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(); 

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

另一个可能更直观的选择是使用 Basics 包:

 // the birthday's date
 final birthday = DateTime(1967, 10, 12);
 final today = DateTime.now();
 final difference = (today - birthday).inDays;

有关软件包的更多信息:https://pub.dev/packages/basics

获取两个日期之间的差异

要找出两个 DateTime 对象之间的时间间隔,请使用 difference, which returns a Duration 对象:

final birthdayDate = DateTime(1967, 10, 12);
final toDayDate = DateTime.now();
var different = toDayDate.difference(birthdayDate).inDays;

print(different); // 19362

差异以秒和秒的分数来衡量。上面的差异计算了这些日期开始时午夜之间的小数秒数。如果上面的日期是当地时间,而不是 UTC,那么由于夏令时差异,两个午夜之间的差异可能不是 24 小时的倍数。

如果在此之后发生其他情况,则返回的 Duration 将为负值。

所有这些答案都遗漏了一个关键部分,那就是闰年。

这是计算年龄的完美解决方案:

calculateAge(DateTime birthDate) {
  DateTime currentDate = DateTime.now();
  int age = currentDate.year - birthDate.year;
  int month1 = currentDate.month;
  int month2 = birthDate.month;
  if (month2 > month1) {
    age--;
  } else if (month1 == month2) {
    int day1 = currentDate.day;
    int day2 = birthDate.day;
    if (day2 > day1) {
      age--;
    }
  }
  return age;
}

DateTime 延期

有了 extension class 你可以:

int days = birthdate.daysSince;

示例extension class:

extension DateTimeExt on DateTime {
  int get daysSince => this.difference(DateTime.now()).inDays;
}

如果有人想找出秒、分钟、小时和天的形式差异。那么这是我的方法。

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';
  }
var start_date = "${DateTime.now()}";
var fulldate =start_date.split(" ")[0].split("-");
var year1 = int.parse(fulldate[0]);
var mon1 = int.parse(fulldate[1]);
var day1 = int.parse(fulldate[2]);
var date1 = (DateTime(year1,mon1,day1).millisecondsSinceEpoch);
var date2 = DateTime(2021,05,2).millisecondsSinceEpoch;
var Difference_In_Time = date2 - date1;
var Difference_In_Days = Difference_In_Time / (1000 * 3600 * 24);
print(Difference_In_Days); ```

当心未来选择答案的“错误”

所选答案中真正缺少的东西 - 奇怪的是大量投票 - 它会 根据 :

计算两个日期之间的差异

Duration

这意味着如果两个日期的差异小于 24 小时将被认为是相同的!!通常这不是期望的行为。您可以通过稍微调整代码来解决此问题,以便从时钟那天截断:

Datetime from = DateTime(1987, 07, 11); // this one does not need to be converted, in this specific example, but we assume that the time was included in the datetime.
Datetime to = DateTime.now();

print(daysElapsedSince(from, to));

[...]

int daysElapsedSince(DateTime from, DateTime to) {
// get the difference in term of days, and not just a 24h difference
  from = DateTime(from.year, from.month, from.day);  
  to = DateTime(to.year, to.month, to.day);
 
  return to.difference(from).inDays; 
}

因此您可以检测 from 是否在 to 之前,因为它将 return 一个表示天数差异的正整数,否则为负,如果为 0两者都发生在同一天。

documentation 中指出了此功能 return 并且在许多用例中,如果遵循最初选择的答案,它可能会导致一些可能难以调试的问题:

Returns a Duration with the difference when subtracting other (from) from this (to).

希望对您有所帮助。

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

这是正确的:

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();
}

测试:

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!

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

就运行这个:

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);

注意:由于夏令时,某天和第二天之间可能会有 23 小时的差异,即使您标准化为 0:00。这就是以下内容也不正确的原因:

// 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; 
}

咆哮:如果你问我,Dart DateTime很糟糕。它至少应该有基本的东西,比如 daysBetween 和时区处理等


更新:https://pub.dev/packages/time_machine声称是Noda Time的一个端口。如果是这样,并且它被正确移植(我还没有测试过)那么这就是你应该使用的 Date/Time 包。

天真地用 DateTime.difference is subtly wrong. As explained by the DateTime documentation 从另一个中减去一个 DateTime:

The difference between two dates in different time zones is just the number of nanoseconds between the two points in time. It doesn't take calendar days into account. That means that the difference between two midnights in local time may be less than 24 hours times the number of days between them, if there is a daylight saving change in between.

您可以使用 UTC DateTime objects[=37= 在 DateTime 计算中忽略夏令时,而不是四舍五入计算的天数]1 因为 UTC 不遵守夏令时。

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

/// 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;
}

1 请注意,将本地 DateTime 对象转换为 .toUtc() 的 UTC 将无济于事; dateTimedateTime.toUtc() 都代表同一时刻,所以 dateTime1.difference(dateTime2)dateTime1.toUtc().difference(dateTime.toUtc()) 会 return 相同 Duration.

以上答案也正确,我只是创建了一个单一的方法来找出两天之间的差异,当天接受。

  void differenceBetweenDays() {
    final date1 = DateTime(2022, 01, 01); // 01 jan 2022
    final date2 = DateTime(2022, 02, 01); // 01 feb 2022
    final currentDay = DateTime.now(); // Current date
    final differenceFormTwoDates = daysDifferenceBetween(date1, date2);
    final differenceFormCurrent = daysDifferenceBetween(date1, currentDay);

    print("difference From date1 and date 2 :- "+differenceFormTwoDates.toString()+" "+"Days");
    print("difference From date1 and Today :- "+differenceFormCurrent.toString()+" "+"Days");

  }
  int daysDifferenceBetween(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();
  }