Flutter - 如何找到年、月和日中的两个日期之间的差异?

问题描述 投票:0回答:13

我正在寻找一种方法来使用

DateTime
来解析两个日期,以显示差异。 我想把它放在格式上:“X 年,Y 个月,Z 天”。

对于 JS,我们有

momentjs
库和 以下代码::

var a = moment([2015, 11, 29]);
var b = moment([2007, 06, 27]);

var years = a.diff(b, 'year');
b.add(years, 'years');

var months = a.diff(b, 'months');
b.add(months, 'months');

var days = a.diff(b, 'days');

console.log(years + ' years ' + months + ' months ' + days + ' days');
// 8 years 5 months 2 days

dart 是否有类似的库可以帮助实现这个用例?

datetime flutter dart date-difference
13个回答
6
投票

我认为使用 DateTime 不可能轻松地完成您想要的操作。因此,您可以使用 https://pub.dev/packages/time_machine 包,它在日期时间处理方面非常强大:

import 'package:time_machine/time_machine.dart';

void main() {
  LocalDate a = LocalDate.today();
  LocalDate b = LocalDate.dateTime(DateTime(2022, 1, 2));
  Period diff = b.periodSince(a);
  print("years: ${diff.years}; months: ${diff.months}; days: ${diff.days}");
}

小时/分钟/秒精度:

import 'package:time_machine/time_machine.dart';

void main() {
  LocalDateTime a = LocalDateTime.now();
  LocalDateTime b = LocalDateTime.dateTime(DateTime(2022, 1, 2, 10, 15, 47));
  Period diff = b.periodSince(a);
  print("years: ${diff.years}; months: ${diff.months}; days: ${diff.days}; hours: ${diff.hours}; minutes: ${diff.minutes}; seconds: ${diff.seconds}");
}

5
投票

你要找的是 Dart DateTime 类 你可以在 moment.js 中接近你想要的东西

main() {
  var a = DateTime.utc(2015, 11, 29);
  var b = DateTime.utc(2007, 06, 27);

  var years = a.difference(b);
  print(years.inDays ~/365);

}

DateTime 没有 inYears 或 inMonths 选项,尽管这就是年份在打印中分开的原因。 差异函数以秒为单位返回差异,因此您必须自己处理几天。


2
投票

你可以写一个关于持续时间类的扩展来格式化它:

extension DurationExtensions on Duration {
  String toYearsMonthsDaysString() {
    final years = this.inDays ~/ 365
    // You will need a custom logic for the months part, since not every month has 30 days
    final months = (this.inDays ~% 365) ~/ 30
    final days = (this.inDays ~% 365) ~% 30

    return "$years years $months months $days days";
  }
}

用法将是:

final date1 = DateTime()
final date2 = DateTime()
date1.difference(date2).toYearsMonthsDaysString()

2
投票

你可以像这样使用Jiffy Package

var jiffy1 = Jiffy("2008-10", "yyyy-MM");
var jiffy2 = Jiffy("2007-1", "yyyy-MM");

jiff1.diff(jiffy2, Units.YEAR); // 1
jiff1.diff(jiffy2, Units.YEAR, true);

2
投票

可以从总天数计算:

void main() {
  DateTime a = DateTime(2015, 11, 29);
  DateTime b = DateTime(2007, 06, 27);
  int totalDays = a.difference(b).inDays;
  int years = totalDays ~/ 365;
  int months = (totalDays-years*365) ~/ 30;
  int days = totalDays-years*365-months*30;
  print("$years $months $days $totalDays");
}

结果是:8 5 7 3077


2
投票

我为公历日期创建了自己的类,并创建了一个方法来处理这个问题,它“逻辑上”计算两个日期之间的年、月和日差异...... 我实际上是在没有使用任何其他包(包括 DateTime 包)的情况下从头开始创建类的,但在这里我使用 DateTime 包来说明这种方法是如何工作的。直到现在它对我来说都很好......

判断是否闰年的方法:

    static bool leapYear(DateTime date) {
    if(date.year%4 == 0) {
      if(date.year%100 == 0){
        return date.year%400 == 0;
      }
      return true;
    }
    return false;
  }

这是计算两个日期之间的年、月、日差的方法。它将结果放入整数列表中:

     static List<int> differenceInYearsMonthsDays(DateTime dt1, DateTime dt2) {
    List<int> simpleYear = [31,28,31,30,31,30,31,31,30,31,30,31];
    if(dt1.isAfter(dt2)) {
      DateTime temp = dt1;
      dt1 = dt2;
      dt2 = temp;
    }
    int totalMonthsDifference = ((dt2.year*12) + (dt2.month - 1)) - ((dt1.year*12) + (dt1.month - 1));
    int years = (totalMonthsDifference/12).floor();
    int months = totalMonthsDifference%12;
    late int days;
    if(dt2.day >= dt1.day) {days = dt2.day - dt1.day;}
    else {
      int monthDays = dt2.month == 3
          ? (leapYear(dt2)? 29: 28)
          : (dt2.month - 2 == -1? simpleYear[11]: simpleYear[dt2.month - 2]);
      int day = dt1.day;
      if(day > monthDays) day = monthDays;
      days = monthDays - (day - dt2.day);
      months--;
    }
    if(months < 0) {
      months = 11;
      years--;
    }
    return [years, months, days];
  }

计算两个日期之间的月、日差的方法:

static List<int> differenceInMonths(DateTime dt1, DateTime dt2){
    List<int> inYears = differenceInYearsMonthsDays(dt1, dt2);
    int difMonths = (inYears[0]*12) + inYears[1];
    return [difMonths, inYears[2]];
  }

计算两个日期天数之差的方法:

static int differenceInDays(DateTime dt1, DateTime dt2) {
    if(dt1.isAfter(dt2)) {
      DateTime temp = dt1;
      dt1 = dt2;
      dt2 = temp;
    }
    return dt2.difference(dt1).inDays;
  }

用法示例:

void main() {
  DateTime date1 = DateTime(2005, 10, 3);
  DateTime date2 = DateTime(2022, 1, 12);
  List<int> diffYMD = GregorianDate.differenceInYearsMonthsDays(date1, date2);
  List<int> diffMD = GregorianDate.differenceInMonths(date1, date2);
  int diffD = GregorianDate.differenceInDays(date1, date2);

  print("The difference in years, months and days: ${diffYMD[0]} years, ${diffYMD[1]} months, and ${diffYMD[2]} days.");
  print("The difference in months and days: ${diffMD[0]} months, and ${diffMD[1]} days.");
  print("The difference in days: $diffD days.");
}

输出:

The difference in years, months and days: 16 years, 3 months, and 9 days.
The difference in months and days: 195 months, and 9 days.
The difference in days: 5945 days.

1
投票

答案是肯定的,你可以使用 Dart 中的 DateTime 类轻松实现它。请参阅:https://api.dart.dev/stable/2.8.3/dart-core/DateTime-class.html

例子

void main() {
  var moonLanding = DateTime(1969,07,20)
  var marsLanding = DateTime(2024,06,10);
  var diff = moonLanding.difference(marsLanding);

  print(diff.inDays.abs());
  print(diff.inMinutes.abs());
  print(diff.inHours.abs());
}

输出: 20049 28870560 481176


1
投票
final firstDate = DateTime.now();
final secondDate = DateTime(firstDate.year, firstDate.month - 20);

final yearsDifference = firstDate.year - secondDate.year;
final monthsDifference = (firstDate.year - secondDate.year) * 12 +
    firstDate.month - secondDate.month;
final totalDays = firstDate.difference(secondDate).inDays;

简单的方法,不需要包。


1
投票

使用以下代码尝试 intl 包:

import 'package:intl/intl.dart';

String startDate = '01/01/2021';
String endDate = '01/01/2022';

final start = DateFormat('dd/MM/yyyy').parse(startDate);
final end = DateFormat('dd/MM/yyyy').parse(endDate);

然后,您可以使用以下代码计算两个日期之间的持续时间:

final duration = end.difference(start);

要获取年月日数,可以这样做:

final years = duration.inDays / 365;
final months = duration.inDays % 365 / 30;
final days = duration.inDays % 365 % 30;

最后,您可以使用这些变量以所需格式显示结果:

    final result = '${years.toInt()} years ${months.toInt()} months y ${days.toInt()} days';

0
投票

DateTime 年差是一个特定的函数,像这样:

  static int getDateDiffInYear(DateTime dateFrom, DateTime dateTo) {
    int sign = 1;
    if (dateFrom.isAfter(dateTo)) {
      DateTime temp = dateFrom;
      dateFrom = dateTo;
      dateTo = temp;
      sign = -1;
    }
    int years = dateTo.year - dateFrom.year;
    int months = dateTo.month - dateFrom.month;
    if (months < 0) {
      years--;
    } else {
      int days = dateTo.day - dateFrom.day;
      if (days < 0) {
        years--;
      }
    }
    return years * sign;
  }

0
投票

答案可能有点长,但会给你你所需要的。

这将为您提供格式为“年:年,月:月,日:天”的字符串值。您可以根据需要更改它。

您需要调用 differenceInYearsMonthsAndDays() 并传递 startDate 和 endDate。

一个扩展来计算月份的差异,丢弃多余的天数。

extension DateTimeUtils on DateTime {
  int differenceInMonths(DateTime other) {
    if (isAfter(other)) {
      if (year > other.year) {
        if (day >= other.day) {
          return (12 + month) - other.month;
        } else {
          return (12 + month - 1) - other.month;
        }
      } else {
        if (day >= other.day) {
          return month - other.month;
        } else {
          return month - 1 - other.month;
        }
      }
    } else {
      return 0;
    }
  }
}

一种生成年月日格式的方法

String differenceInYearsMonthsAndDays(
  DateTime startDate,
  DateTime endDate,
) {
  int days;
  final newStartDate = startDate.add(const Duration(days: -1));
  int months = endDate.differenceInMonths(newStartDate);
  if(months >= 12) {
    final years = months ~/ 12;
    final differenceInMonthsAndDays = differenceInMonthsAndDays(
          startDate.add(const Duration(year: years), 
          endDate,
    );
    return "Years : years, $differenceInMonthsAndDays";
  } else {
    return differenceInMonthsAndDays(
          startDate, 
          endDate,
    );
  }

}

一种生成月日格式的方法

String differenceInMonthsAndDays(
  DateTime startDate,
  DateTime endDate,
) {
  int days;
  final newStartDate = startDate.add(const Duration(days: -1));
  int months = endDate.differenceInMonths(newStartDate);


  if (months > 0) {
    final tempDate = DateTime(
      newStartDate.year,
      newStartDate.month + months,
      newStartDate.day,
    );
    days = endDate.difference(tempDate).inDays;
    return days > 0 
       ? "Months : $months, Days : $days" 
       : "Months : $months";
  } else {
    days = endDate.difference(newStartDate).inDays;
    return "Days : $days";
  }
}

0
投票

年份和月份有些特殊。上面的大部分回复都没有考虑闰年(并非所有年份都有 365 天,因此在某些情况下除以它可能会给你错误的结果)以及并非所有月份都是 30 天的事实..

我发现计算自某个日期以来过去的年数的最简单方法如下:

int _getYearDifference(DateTime from, DateTime to) {
    var diff = to.year - from.year;
    if (to.month < from.month || (to.month == from.month && to.day < from.day)) {
        diff--;
    }
    return diff;
}

同样months:

int _getMonthDifference(DateTime from, DateTime to) {
  int yearDiff = to.year - from.year;
  int monthDiff = max(to.month - from.month, 0);

  int diff = yearDiff * 12 + monthDiff;

  if (monthDiff > 0 && to.day < from.day) {
    diff--;
  }

  return diff;
}

对于天和更短的间隔,您可以使用标准的

difference()
方法:

var diff = to.difference(from);
print(diff.inDays.abs());

-2
投票
difHour = someDateTime.difference(DateTime.now()).inHours;
    difMin = (someDateTime.difference(DateTime.now()).inMinutes)-(difHour*60);

多年和几天都一样

© www.soinside.com 2019 - 2024. All rights reserved.