Dart datetime difference in weeks, month and years
Asked Answered
D

5

5

I was working on a project and wanted to add the difference in DateTime in terms of minutes, hours, days, weeks, months and years. I was able to get in minutes up to days. e.g.

DateTime.now().difference(DateTime(2019, 10, 7)).inDays

But I had a hard time creating it for weeks, months and years. How can I do so, please help

Dambro answered 14/10, 2019 at 11:21 Comment(5)
What have you tried? Converting between a number of days to weeks should be straightforward. For months, how do you define the length of a month?Krp
based on an array which has days on the 12 months _daysInMonthArray = [0,31,28,31,30,31,30,31,31,30,31,30,31]; where array 1 is JanDambro
How many "months" is it between January 31 and February 1? 0? 1? How about between January 16 and February 13 (a span of 28 days)? Would that be measured against the number of days in January or in February?Krp
@Krp I was able to create my own way referencing from momentjs on how they handle diff, will post it belowDambro
@Krp I have posted my answer, please see below, and tell me what you thinkDambro
D
6

I constructed a package to help me with this called Jiffy

Jiffy([2018, 1, 29]).diff(Jiffy([2019, 10, 7]), Units.DAY); // -616
Jiffy([2018, 1, 29]).diff(Jiffy([2019, 10, 7]), Units.WEEK); // -88
Jiffy([2018, 1, 29]).diff(Jiffy([2019, 10, 7]), Units.MONTH; // -20
Jiffy([2018, 1, 29]).diff(Jiffy([2019, 10, 7]), Units.YEAR); // -1
Dambro answered 15/10, 2019 at 7:18 Comment(1)
Great package! Really helped me outManilla
K
6

you can calculate month diff size manually (without use any packege):

      static int getMonthSizeBetweenDates(DateTime initialDate, DateTime endDate){
    return calculateMonthSize(endDate)-calculateMonthSize(initialDate)+1;
  }

  static int calculateMonthSize(DateTime dateTime){
    return dateTime.year*12+dateTime.month;
  }

getMonthSizeBetweenDates method gives you how many months between your initial and end dates. for example : your initial date is 1.1.2022 and your end date is 1.3.2022 . then this method return 3 (january, fabruary and march)

You can find week and year diff bye using this logic.

Another method:

static int getMonthSizeBetweenDates2(DateTime initialDate, DateTime endDate){
    return (endDate.year-initialDate.year)*12+(endDate.month-initialDate.month)+1;
  }
Kiyokokiyoshi answered 18/2, 2022 at 8:19 Comment(1)
This solution worked very well. But note that the diff includes both start and end months also.Omophagia
J
2

There is a very simple and easy way to do this, and requires very little date/time arithmetic knowledge.

Simply compare both DateTimes' microsecondSinceEpoch values:

Duration compare(DateTime x, DateTime y) {
   return Duration(microseconds: (x.microsecondsSinceEpoch - y.microsecondsSinceEpoch).abs())
}

DateTime x = DateTime.now()
DateTime y = DateTime(1994, 11, 1, 6, 55, 34);

Duration diff = compare(x,y);

print(diff.inDays);
print(diff.inHours);
print(diff.inMinutes);
print(diff.inSeconds);

The code above works, and works much more efficiently than conducting checks for leap-years and aberrational time-based anomalies.

To get larger units, we can just approximate. Most end-users are satisfied with a general approximation of this sort:

Weeks: divide days by 7 and round.

Months: divide days by 30.44 and round; if < 1, display months instead.

Years: divide days by 365.25 and floor, and also display months modulo 12.

Justificatory answered 1/11, 2019 at 23:30 Comment(3)
Except for that only works up to days, not months, weeks, or years.Rearward
Weeks: divide days by 7 and round. Months: divide days by 30.44 and round. Years: divide days by 365.25 and floor, and also display months modulo 12. In the vast majority of cases, this ad-hoc approximation is more than fine...Justificatory
I'll update the answer to include this information.Justificatory
S
1

To enhance the answer provided by AKushWarrior You can create a Helper Function like this and use it wherever required. Its a static function so you don't even need instance.

static String calculateTime(DateTime time) {
    Duration compare(DateTime x, DateTime y) {
      return Duration(microseconds: (x.microsecondsSinceEpoch - y.microsecondsSinceEpoch).abs());
    }

DateTime x = DateTime.now();
DateTime y = time;

Duration diff = compare(x,y);
int days = diff.inDays;
int hours = diff.inHours;
int minutes = diff.inMinutes;

String result = '';
if(days > 365){ result =  '${(days/365).floor().toString()} Year(s)'; }
else if(days > 30){ result =  '${(days/30).floor().toString()} Month(s)'; }
else if(days > 7){ result =  '${(days/7).floor().toString()} Week(s)'; }
else if(days > 1){ result =  '${(days/1).floor().toString()} Day(s)'; }
else if(hours > 1){ result =  '$hours Hour(s)'; }
else if(minutes > 1){ result =  '$minutes Minute(s)'; }
else{ result =  'Now'; }

return result;

}

Shoveler answered 19/3, 2023 at 16:16 Comment(0)
O
0

I have found a package that does approximate conversion of Duration to human readable text https://pub.dev/packages/humanizer

Append your Duration with .toApproximateTime(round: false, isRelativeToNow: false)

Obverse answered 10/10 at 22:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.