【问题标题】:Flutter: Find the number of days between two datesFlutter:查找两个日期之间的天数
【发布时间】:2022-05-08 01:05:33
【问题描述】:

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

用户的出生日期

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

今天的日期

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

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

是否有任何特定的公式或软件包可供我查看?

【问题讨论】:

    标签: flutter date dart difference


    【解决方案1】:

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

    【讨论】:

    • 为什么它在晚上 11 点计算 +1?
    • 有时这种方法不符合预期DateTime.parse("2020-01-10 00:00:00.299871").difference(DateTime.parse("2020-01-09 23:00:00.299871")).inDays = 0
    • difference 计算两个时间点之间的毫秒或微秒,然后inDays 返回该时间的完整“天”数(24 个完整小时),向下舍入。要计算两个日期之间的日历天数,日期应具有完全相同的小时/分钟/秒/毫秒/微秒(例如零)并且是 UTC 天数 - 因为由于夏令时,某些本地时间天数为 23 或 25 小时.然后就可以了。
    • 当差值小于24h时,不算一整天。但我想知道今天是今天还是明天。
    • 这个答案是错误的。不要使用它。我发布了另一个答案,其中考虑了一天中的时间和夏令时。
    【解决方案2】:

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

    这是正确的:

    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 包。

    【讨论】:

    • 如果您向我的答案发送更新会很棒:)
    • 如果你的daysBetween 函数使用DateTime.utc 构造函数代替四舍五入,它会更简洁。 UTC DateTime 对象不遵守 DST。
    • 我认为@jamesdlin 是正确的,这会返回正确的值:return DateTime.utc(date1.year, date1.month, date1.day).difference(DateTime.utc(date2.year, date2.month, date2.day)).inDays;
    【解决方案3】:

    使用 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
    

    【讨论】:

    • 不回答,如何计算天差。
    • 已经在我的第一个示例中提到了这一点。最终差异InDays = dateTimeNow.difference(dateTimeCreatedAt).inDays;
    • 我想你提到了如何计算与 DateTime.now() 的差异。这些问题询问两个日期之间的差异(不同于 .now())。
    【解决方案4】:

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

    【讨论】:

    • 不处理闰年,所以关闭日期不正确
    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

      提防未来选择答案的“错误”

      所选答案中真正缺少的东西 - 奇怪地被大量赞成 - 是它将计算两个日期之间的差异

      持续时间

      这意味着如果相差少于 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。

      documentation 中指出了此函数返回的内容,在许多用例中,如果遵循原始选择的答案,可能会导致一些可能难以调试的问题:

      从这个 (to) 中减去其他 (from) 时返回一个 Duration。

      希望对你有帮助。

      【讨论】:

        【解决方案7】:

        天真地用DateTime.difference 从另一个中减去一个DateTime 是错误的。 正如the DateTime documentation 所解释的:

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

        您可以使用 UTC DateTime objects1DateTime 计算中忽略夏令时,而不是四舍五入计算的天数,因为 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 对象转换为 UTC 与 .toUtc() 将无济于事; dateTimedateTime.toUtc() 都代表相同的时间点,因此 dateTime1.difference(dateTime2)dateTime1.toUtc().difference(dateTime.toUtc()) 将返回相同的 Duration

        【讨论】:

          【解决方案8】:

          获取两个日期之间的差异

          要找出两个 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 将为负数。

          【讨论】:

            【解决方案9】:

            另一个可能更直观的选择是使用 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

            【讨论】:

            • package:basics 现在提供了一个 calendarDaysTill 扩展方法,可以计算两个日期之间的天数差异。
            【解决方案10】:

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

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

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

            【讨论】:

              【解决方案11】:
              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); ```
              

              【讨论】:

                【解决方案12】:

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

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

                【讨论】:

                  【解决方案13】:

                  日期时间的扩展

                  使用extension 课程,您可以:

                  int days = birthdate.daysSince;
                  

                  例如extension类:

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

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-02-25
                    • 2016-03-15
                    • 2017-05-17
                    • 1970-01-01
                    • 2017-07-05
                    • 2011-08-29
                    • 2011-03-01
                    相关资源
                    最近更新 更多