skip to Main Content

I have created a birthday reminder app where i have data like events..

Now i want to show upcoming birthday with sorting and want to show on listview builder

void main() {


  List<EventModel> events = [
  EventModel(
    title: 'A',
    date: DateTime(1980, 08, 12),
  ),
  EventModel(
  title: 'Z',
  date: DateTime(2020, 12, 28),
  ),
  EventModel(
  title: 'B',
  date: DateTime(1995, 12, 21),
  ),
];
   events.sort((a, b) => (a.date).compareTo(b.date));

   for(var x in events)
     print(x.date.toString());



}

above code giving me output as it is sorting entire date including year..how to sort based on month and day only..

1980-08-12 00:00:00.000
1995-12-21 00:00:00.000
2020-12-28 00:00:00.000

I need following output as upcoming birthday is like

2020-12-28 00:00:00.000
1980-08-12 00:00:00.000
1995-12-21 00:00:00.000


2

Answers


  1. I think you can achieve your goals by simply writing a custom comparator that only compares the months and days.

    int Function(DateTime, DateTime) createCompartor(DateTime referenceDate) {
      int compareDates(DateTime a, DateTime b) {
        // factorA and factorB are 1 when the date (birthday) is next year. 
        final factorA = a.copyWith(year: referenceDate.year).isAfter(referenceDate) ? 0 : 1;
        final factorB = b.copyWith(year: referenceDate.year).isAfter(referenceDate) ? 0 : 1;
        
        // Using factorA and factorB, we create new dates where birthdays that
        // are in the next year are larger than the birthdays that are in this
        // remaining year.
        return a.copyWith(year: referenceDate.year + factorA).compareTo(b.copyWith(year: referenceDate.year + factorB));
      }
      
      return compareDates;
    }
    
    void main() {
    
    
      List<DateTime> events = [
        DateTime(2023, 8, 8),
        DateTime(2002, 11, 11),
        DateTime(1990, 12, 29),
        DateTime(2023, 1, 1),
        DateTime(2020, 12, 28),
      ];
      
      events.sort(createCompartor(DateTime.now()));
    
      for(var x in events)
        print(x.toString());
    }
    

    Outputs

    2020-12-28 00:00:00.000
    1990-12-29 00:00:00.000
    2023-01-01 00:00:00.000
    2023-08-08 00:00:00.000
    2002-11-11 00:00:00.000
    
    Login or Signup to reply.
  2. check comments of @jamesdlin its useful to solve ur problem

    i have created a method named ignoreYear which return a date ignoring year and it will check whether date is before or after of today date…

    here is your solution..

    you might get some expert code but here is basic code…

    DateTime ignoreYear(DateTime date) {
      final now = DateTime.now();
      var today = DateTime.utc(now.year, now.month, now.day);
      var next = DateTime.utc(today.year, date.month, date.day);
    
      if (next.isBefore(today)) {
        next = next.copyWith(year: today.year + 1);
      }
      return next;
    }
    
    void main() {
      events.sort((a, b) => ignoreYear(a.date).compareTo(ignoreYear(b.date)));
    
      for (var x in events) print(x.date.toString());
    }
    
    

    All credit goes to jamesdlin

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search