【问题标题】:Get Last Month Date In Flutter / Dart在 Flutter / Dart 中获取上个月的日期
【发布时间】:2018-12-27 11:14:19
【问题描述】:

在颤振中,我们可以使用这个得到当前月份

var now = new DateTime.now();
var formatter = new DateFormat('MM');
String month = formatter.format(now);

但是如何获得上个月的日期呢?特别是如果当前日期是一月 (01)。当我们使用操作数减号 (-) 时,我们无法得到正确的月份,例如月份 - 1。

【问题讨论】:

    标签: datetime dart flutter


    【解决方案1】:

    要在月初设置一个起点,您可以使用DateTimeJiffy 包。

    DateTime firstOfPreviousMonth 
      = DateTime.parse(
          Jiffy().startOf(Units.MONTH)
               .subtract(months: 1)
               .format('yyyy-MM-dd'). //--> Jan 1 '2021-01-01 00:00:00.000'
      );  
    
    var fifthOfMonth 
      = firstOfPreviousMonth.add(Duration(days: 4)); //--> Jan 5 '2021-01-05 00:00:00.000'
    

    DateTime endOfPreviousMonth 
      = DateTime.parse(
          Jiffy().endOf(Units.MONTH)
               .subtract(months: 2)
               .format('yyyy-MM-dd'). //--> Dec 30 '2020-12-31 00:00:00.000' 
                                      // endOf always goes to 30th
      );  
    
    var previousMonth 
          = endOfPreviousMonth.add(Duration(days: 2)); //--> Jan 1 '2021-01-01 00:00:00.000'
    

    【讨论】:

      【解决方案2】:

      我们可以计算当月的第一天和当月的最后一天:

      DateTime firstDayCurrentMonth = DateTime.utc(DateTime.now().year, DateTime.now().month, 1);
      
      DateTime lastDayCurrentMonth = DateTime.utc(DateTime.now().year,DateTime.now().month+1,).subtract(Duration(days: 1));
      

      DateTime.utc 接受整数值作为参数:int year、int month、int day 等。

      【讨论】:

        【解决方案3】:

        试试这个包,Jiffy,它使用了momentjs 语法。见下文

        Jiffy().subtract(months: 1);
        

        Jiffy() 现在返回日期。也可以这样做,结果一样

        var now = DateTime.now();
        Jiffy(now).subtract(months: 1);
        

        【讨论】:

          【解决方案4】:

          日期很难计算。有一个公开的提议来增加对添加年份和月份的支持https://github.com/dart-lang/sdk/issues/27245

          在“a 月”和“一年”不是一个具体的时间量。年份相差一个 天,月最多三天。在 30 日加上“一个月” 一月是模棱两可的。我们可以做到,我们只需要挑选一些 2 月 27 日至 3 月 2 日之间的任意一天。 这就是为什么我们没有在 Duration 中添加月份和年份 - 他们没有 描述持续时间。

          您可以使用以下代码以任意方式添加月份(我认为它不完全准确。取自问题)

          const _daysInMonth = const [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
          
          bool isLeapYear(int value) =>
              value % 400 == 0 || (value % 4 == 0 && value % 100 != 0);
          
          int daysInMonth(int year, int month) {
            var result = _daysInMonth[month];
            if (month == 2 && isLeapYear(year)) result++;
            return result;
          }
          
          DateTime addMonths(DateTime dt, int value) {
            var r = value % 12;
            var q = (value - r) ~/ 12;
            var newYear = dt.year + q;
            var newMonth = dt.month + r;
            if (newMonth > 12) {
              newYear++;
              newMonth -= 12;
            }
            var newDay = min(dt.day, daysInMonth(newYear, newMonth));
            if (dt.isUtc) {
              return new DateTime.utc(
                  newYear,
                  newMonth,
                  newDay,
                  dt.hour,
                  dt.minute,
                  dt.second,
                  dt.millisecond,
                  dt.microsecond);
            } else {
              return new DateTime(
                  newYear,
                  newMonth,
                  newDay,
                  dt.hour,
                  dt.minute,
                  dt.second,
                  dt.millisecond,
                  dt.microsecond);
            }
          }
          

          【讨论】:

            【解决方案5】:

            除了Günter Zöchbauer回答

            var now = new DateTime.now();
                String g = ('${now.year}/ ${now.month}/ ${now.day}');
                print(g);
            

            【讨论】:

              【解决方案6】:

              我们可以使用减法来获取过去的月份日期。

              DateTime pastMonth = DateTime.now().subtract(Duration(days: 30));
              

              【讨论】:

              • 这在任何给定月份的 31 日都行不通......而且在 2 月它可能会倒退两个月。
              • DateTime createdAt = Timestamp.now().toDate(); createdAt.subtract(Duration(days: 7)); print("createdAt: $createdAt"); 不适合我。打印当前时间戳,而不是提前 7 天 datetime 。请建议。谢谢。
              【解决方案7】:

              你可以使用

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

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

              你得到

              2017-12-13
              

              在进行日期计算之前,最好先转换为 UTC,然后再返回本地日期/时间,以避免出现夏令时和时区问题。

              【讨论】:

              • 如果你只想要月份,我推荐使用DateTime(date.year, date.month - 1, 1)。如果您使用date.day,则可能会在 3 月 31 日之前溢出。 “哪一天是 3 月 31 日之前的一个月”没有明显的答案,不同的用例会需要不同的答案(但 3 月 3 日通常不是任何人想要的:微笑:)。要获取上个月的最后天,请使用DateTime(date.year, date.month, 0)
              • 很好的解释。我会用它
              • 我们如何获得当前月份的最后日期?
              • 为下个月的第一天创建一个日期并减去一天。
              猜你喜欢
              • 1970-01-01
              • 2020-03-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-11-25
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多