簡體   English   中英

Flutter:求兩個日期之間的天數

[英]Flutter: Find the number of days between two dates

我目前有一個用戶的個人資料頁面,其中顯示了他們的出生日期和其他詳細信息。 但是我打算通過計算今天的日期和從用戶那里獲得的出生日期之間的差值來找到他們生日前幾天。

用戶的出生日期

用戶出生日期

這是使用國際 package獲得的今天日期。

今天的日期

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

我現在面臨的問題是,如何計算這兩個日期的天數差異?

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

您可以使用DateTime類提供的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);

這是帶有完整解釋的原始答案: https ://stackoverflow.com/a/67679455/666221

接受的答案是錯誤的。 不要使用它。

這是對的:

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

Rant:如果你問我,Dart DateTime非常糟糕。 它至少應該有基本的東西,比如daysBetween和時區處理等。


更新:https://pub.dev/packages/time_machine聲稱是 Noda Time 的一個端口。 如果是這種情況,並且它被正確移植(我還沒有測試過),那么這就是你應該使用的 Date/Time 包。

使用 DateTime 類找出兩個日期之間的差異。

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

或者

您可以使用jiffy Jiffy 是一個日期 dart 包,靈感來自 momentjs,用於解析、操作和格式化日期。

示例: 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

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

如果有人想以秒、分鍾、小時和天的形式找出差異。 然后這是我的方法。

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

天真地用DateTime從另一個中減去一個DateTime.difference是錯誤的。 正如DateTime文檔所解釋的:

不同時區的兩個日期之間的差異只是兩個時間點之間的納秒數。 它不考慮日歷天數。 這意味着當地時間的兩個午夜之間的差異可能小於 24 小時乘以它們之間的天數,如果兩者之間有夏令時變化。

您可以使用UTC DateTime對象1DateTime計算中忽略夏令時,而不是舍入計算的天數,因為 UTC 不遵守 DST。

因此,要計算兩個日期之間的天數差,忽略時間(也忽略夏令時調整和時區),構造具有相同日期並使用相同時間的新 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;
}

更新

我在package:basics中添加了一個calendarDaysTill擴展方法,可以做到這一點。


1請注意,使用.toUtc()將本地DateTime對象轉換為 UTC 將無濟於事; dateTimedateTime.toUtc()都代表相同的時間點,因此dateTime1.difference(dateTime2)dateTime1.toUtc().difference(dateTime.toUtc())將返回相同的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之前,因為它將返回一個正整數,表示天數的差異,否則為負數,如果兩者都發生在同一天,則返回 0。

文檔中指出了此函數返回的內容,並且在許多用例中,如果遵循原始選擇的答案,它可能會導致一些可能難以調試的問題:

從 this ( to ) 中減去 other (from)時,返回具有差異的 Duration。

希望能幫助到你。

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

}

最簡單的解決方案:

// d2.difference(d1).inDays

void main() {
  final d1 = DateTime.now();
  final d2 = d1.add(Duration(days: 2));
  print(d2.difference(d1).inDays);
}

DartPad 示例上查看

獲取兩個日期之間的差異

要找出兩個 DateTime 對象之間有多少時間,請使用difference ,它返回一個Duration對象:

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

print(different); // 19362

差異以秒和秒的分數來衡量。 上面的差異計算這些日期開始時午夜之間的小數秒數。 如果上述日期是當地時間,而不是 UTC,則由於夏令時差異,兩個午夜之間的差異可能不是 24 小時的倍數。

如果在此之后發生其他情況,則返回的 Duration 將為負數。

另一個可能更直觀的選擇是使用 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

所有這些答案都錯過了一個關鍵部分,那就是閏年。

這是計算年齡的完美解決方案:

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

上面的答案也是正確的,我只是創建了一個單一的方法來找出這兩天之間的差異,當天接受。

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

我目前有一個用戶的個人資料頁面,其中顯示了他們的出生日期和其他詳細信息。 但是我打算通過計算今天的日期和從用戶那里獲得的出生日期之間的差值來找到他們生日前的日子。

用戶的出生日期

用戶DOB

這是使用intl包獲得的今天的日期。

今天的日期

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

我現在面臨的問題是,如何計算這兩個日期的天數差異?

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

日期時間擴展

使用extension類,您可以:

int days = birthdate.daysSince;

示例extension類:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM