【问题标题】:Add/Subtract months/years to date in dart?在飞镖中添加/减去迄今为止的月/年?
【发布时间】:2019-07-14 11:31:33
【问题描述】:

我看到在 dart 中有一个 Duration 类,但它不能用于加/减年或月。你是如何处理这个问题的,我需要从一个日期中减去 6 个月。是否有类似moment.js 之类的飞镖或其他东西? 谢谢

【问题讨论】:

    标签: flutter date dart subtraction


    【解决方案1】:

    日/月/年的增减可以通过DateTime类来完成

    初始化需要显示的日期格式

      var _inputFormat = DateFormat('EE, d MMM yyyy');
      var _selectedDate = DateTime.now();
    

    增加日/月/年:

    _selectedDate = DateTime(_selectedDate.year,
                            _selectedDate.month + 1, _selectedDate.day);
    

    增加日/月/年:

      _selectedDate = DateTime(_selectedDate.year,
                                _selectedDate.month - 1, _selectedDate.day);
    

    以上示例仅适用于月份,类似的方式我们可以增加或减少年份和日期。

    【讨论】:

    • DateTime createdAt = Timestamp.now().toDate(); createdAt.subtract(Duration(days: 7)); print("createdAt: $createdAt"); 不适合我。打印当前时间戳,而不是提前 7 天 datetime 。请建议。谢谢。
    • @Kamlesh "subtract" 不会更改 DateTime,而是返回一个新的 DateTime。所以你必须把你的代码改成createdAt = createdAt.subtract(Duration(days: 7));
    【解决方案2】:
    Future<void> main() async {
      final DateTime now = DateTime.now();
      var kdate = KDate.buildWith(now);
      log("YEAR", kdate.year);
      log("MONTH", kdate.month);
      log("DATE", kdate.date);
      log("Last Year", kdate.lastYear);
      log("Last Month", kdate.lastMonth);
      log("Yesturday", kdate.yesturday);
      log("Last Week Date", kdate.lastWeekDate);
    }
    
    void log(title, data) {
      print("\n$title  ====>  $data");
    }
    
    class KDate {
      KDate({
        this.now,
        required this.year,
        required this.month,
        required this.date,
        required this.lastYear,
        required this.lastMonth,
        required this.yesturday,
        required this.lastWeekDate,
      });
      final DateTime? now;
      final String? year;
      final String? month;
      final String? date;
      final String? lastMonth;
      final String? lastYear;
      final String? yesturday;
      final String? lastWeekDate;
    
      factory KDate.buildWith(DateTime now) => KDate(
            now: now,
            year: (now.year).toString().split(" ")[0],
            month: (now.month).toString().split(" ")[0],
            date: (now.day).toString().split(" ")[0],
            lastYear: (now.year - 1).toString().split(" ")[0],
            lastMonth: DateTime(now.year, now.month, now.month)
                .subtract(Duration(days: 28))
                .toString()
                .split(" ")[0]
                .toString()
                .split("-")[1],
            yesturday: DateTime(now.year, now.month, now.day)
                .subtract(Duration(days: 1))
                .toString()
                .split(" ")[0]
                .toString()
                .split("-")
                .last,
            lastWeekDate: DateTime(now.year, now.month, now.day)
                .subtract(Duration(days: 7))
                .toString()
                .split(" ")[0]
                .toString()
                .split("-")
                .last,
          );
    }
    
    

    【讨论】:

    • 虽然此代码可以回答问题,但提供有关 如何 和/或 为什么 解决问题的附加上下文将改善答案的长期价值。
    【解决方案3】:

    试试这个包,Jiffy。关于一个月中有多少天以及闰年,添加和减去日期时间。它遵循momentjs的简单语法

    您可以使用以下单位进行加减运算

    years, months, weeks, days, hours, minutes, seconds and milliseconds

    增加 6 个月

    DateTime d = Jiffy().add(months: 6).dateTime; // 2020-04-26 10:05:57.469367
    // You can also add you own Datetime object
    DateTime d = Jiffy(DateTime(2018, 1, 13)).add(months: 6).dateTime; // 2018-07-13 00:00:00.000
    

    您也可以使用 dart 方法级联进行链接

    var jiffy = Jiffy().add(months: 5, years: 1);
    
    DateTime d = jiffy.dateTime; // 2021-03-26 10:07:10.316874
    // you can also format with ease
    String s = jiffy.format("yyyy, MMM"); // 2021, Mar
    // or default formats
    String s = jiffy.yMMMMEEEEdjm; // Friday, March 26, 2021 10:08 AM
    

    【讨论】:

    • 有趣的包。如果都是基于扩展方法就更好了
    【解决方案4】:

    在不使用任何库的情况下,您可以简单地添加 MonthYear

    var date = new DateTime(2021, 1, 29);

    添加月份:-

     date = DateTime(date.year, date.month + 1, date.day);
    

    添加年份:-

     date = DateTime(date.year + 1, date.month, date.day);
    

    【讨论】:

    • DateTime createdAt = Timestamp.now().toDate(); createdAt.subtract(Duration(days: 7)); print("createdAt: $createdAt"); 不适合我。打印当前时间戳,而不是提前 7 天 datetime 。请建议。谢谢。
    【解决方案5】:

    没那么简单。

    final date = DateTime(2017, 1, 1);
    final today = date.add(const Duration(days: 1451));
    

    这会导致2020-12-21 23:00:00.000,因为 Dart 会考虑日光来计算日期(所以我的 1451 天缺少 1 小时,这是非常危险的(例如:巴西在 2019 年取消了夏令时,但如果应用程序是在那之前编写的) ,结果将永远是错误的,如果将来重新引入夏令时也是如此))。

    要忽略日光计算,请执行以下操作:

    final date = DateTime(2017, 1, 1);
    final today = DateTime(date.year, date.month, date.day + 1451);
    

    是的。天是 1451,这没关系。 today 变量现在显示正确的日期和时间:2020-12-12 00:00:00.000

    【讨论】:

      【解决方案6】:

      addsubtract 方法与Duration 对象结合使用,以基于另一个对象创建新的DateTime 对象。

      var date1 = DateTime.parse("1995-07-20 20:18:04");
      
      var newDate = date1.add(Duration(days: 366));
      
      print(newDate); // => 1996-07-20 20:18:04.000
      

      请注意,添加的持续时间实际上是 50 * 24 * 60 * 60 秒。如果生成的 DateTime 具有与此不同的夏令时偏移量,则结果将不会具有与此相同的时间,甚至可能不会在 50 天后达到日历日期。

      在使用当地时间的日期时要小心。

      【讨论】:

      • 这是正确答案。此线程中的其他所有内容都只是丑陋的怪癖。
      • 如何减去50个月?我不工作!
      • DateTime createdAt = Timestamp.now().toDate(); createdAt.subtract(Duration(days: 7)); print("createdAt: $createdAt"); 不适合我。打印当前时间戳,而不是提前 7 天 datetime 。请建议。谢谢。
      【解决方案7】:

      可以减去任何月数。

        DateTime subtractMonths(int count) {
          var y = count ~/ 12;
          var m = count - y * 12;
      
          if (m > month) {
            y += 1;
            m = month - m;
          }
      
          return DateTime(year - y, month - m, day);
        }
      

      同样有效

      DateTime(date.year, date.month + (-120), date.day);
      

      【讨论】:

        【解决方案8】:

        您可以使用subtractadd 方法

        Subtract

        Add

        但你必须将结果重新分配给变量,这意味着:

        这行不通

         date1.add(Duration(days: 1, hours: 23)));
        

        但这会:

         date1 = date1.add(Duration(days: 1, hours: 23)));
        

        例如:

         void main() {
          var d = DateTime.utc(2020, 05, 27, 0, 0, 0);
          d.add(Duration(days: 1, hours: 23));
          // the prev line has no effect on the value of d
          print(d); // prints: 2020-05-27 00:00:00.000Z
        
          //But
          d = d.add(Duration(days: 1, hours: 23));
          print(d); // prints: 2020-05-28 23:00:00.000Z
        }
        

        Dartpad link

        【讨论】:

        • DateTime createdAt = Timestamp.now().toDate(); createdAt.subtract(Duration(days: 7)); print("createdAt: $createdAt"); 不适合我。打印当前时间戳,而不是提前 7 天 datetime 。请建议。谢谢。
        【解决方案9】:

        您可以使用subtractadd 方法

         date1.subtract(Duration(days: 7, hours: 3, minutes: 43, seconds: 56)); 
        
         date1.add(Duration(days: 1, hours: 23)));
        

        Flutter 文档:

        Subtract

        Add

        【讨论】:

        • 我想从一个星期一转到前一个星期一并使用这种方法 (date.subtract(Duration(days: 7));)。但是,这种方法会考虑夏令时,您得到的结果可能会相差一小时。
        • 这不应该是答案,因为它不能解决 OP 的问题,即 Duration 不需要几个月或几年作为参数。但正如你所说,它可以在几天、几小时、几分钟和/或几秒内正常工作:)
        • var myDate = DateTime.parse("2019-09-04 20:18:04Z"); myDate.add(Duration(days: 10)); print("myDate: $myDate"); 它正在打印 myDate: 2019-09-04 20:18:04.000Z 这是不正确的解决方案。
        • 问题是关于添加月/年。而Duration 根本没有这样的属性!
        【解决方案10】:

        好的,您可以分两步完成,取自 @zoechi(Flutter 的主要贡献者):

        定义基准时间,让我们说:

        var date = new DateTime(2018, 1, 13);
        

        现在,你想要新的日期:

        var newDate = new DateTime(date.year, date.month - 1, date.day);
        

        你会得到

        2017-12-13
        

        【讨论】:

        • 它有效,但问题出在momentjs/c#如果你从2000-08-31减去6个月你得到2000-02-29,用dart你得到2000-03-02,不是这样很好。
        • 日期算术很难,并且定义因实现而异。甚至时间都是奇怪的......当您添加跨越 DST 边界的“1 天”时会发生什么?祝你好运,得到你想要的东西。 :)
        • 是的,你是对的,我所做的总结(故事更长 :) 条件更多)是如果当天是当月的最后一天,那么无论你去哪里使用你登陆的月份一个月的最后一天(如果您从 31.08 转到 30.05,从 30.05 转到 30.03 而不是 31.03)
        • 一直在使用这个扩展:dartpad.dev/e3a6375e587ea8f8c61505b8a0888a38 根据你的回答,非常少
        • @polRk 所以new DateTime(date.year, date.month - 50, date.day) 不起作用?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-22
        • 2017-05-25
        • 1970-01-01
        • 2011-04-17
        • 2015-06-21
        • 1970-01-01
        相关资源
        最近更新 更多