3

I am using the below code with the Comparable interface to build a combined list of all the attachments and notes on a record, sorted in descending order of LastModifiedDate

(in constructor of main controller)

rowList = new List <wNA>();

List<Attachment> lstAttachments= [SELECT Id, Name, LastModifiedDate, contentType, OwnerId from Attachment where ParentId =:recordid];                                

for (Integer iDx=0; iDx<lstAttachments.size(); iDx++){
    wNA tr = new wNA();

    String strLastModified = lstAttachments[iDx].LastModifiedDate.format('EEE, d MMM yyyy HH:MM:ss');
    System.debug('  @@@@  Attachments strLastModified: '+strLastModified);

    tr.Type = 'Attachment';
    tr.Id = lstAttachments[iDx].Id;
    tr.fileName = lstAttachments[iDx].Name;
    tr.createdBy =  [SELECT Id, Name from User where Id =:lstAttachments[iDx].OwnerId].Name; 
    tr.contentType = lstAttachments[iDx].contentType;
    tr.LastModifiedDate = lstAttachments[iDx].LastModifiedDate.Date();
tr.LastModifiedDtStr = strLastModified;
    rowList.add(tr);
}

List<Note> lstNotes= [SELECT Id, Title, ParentId, LastModifiedDate, createdbyid, body FROM Note where ParentId =:recordid];

for (Integer iDx=0; idx<lstNotes.size(); idx++){
    wNA tr = new wNA();

    String strLastModified = lstNotes[iDx].LastModifiedDate.format('EEE, d MMM yyyy HH:MM:ss');
    System.debug('  @@@@  strLastModified: '+strLastModified);

    tr.Type = 'Note';
    tr.Id = lstNotes[iDx].Id;
    tr.fileName = lstNotes[iDx].Title;
    tr.createdBy = [SELECT Id, Name from User where Id =:lstNotes[iDx].createdbyid].Name; //lstNotes[iDx].createdbyid;
    tr.LastModifiedDate = lstNotes[iDx].LastModifiedDate;         
    tr.LastModifiedDtStr=strLastModified;
    rowList.add(tr);
    }           

rowList.sort();

} 

and the wrapper class (in the same custom controller):

public List<wNA> rowList {get; set;}  

public class wNA implements Comparable {
    // see http://salesforce.stackexchange.com/questions/106275/how-to-sort-a-custom-list-of-notes-and-attachments-by-lastmodifieddate
    public Integer compareTo(Object o) {            
        return -(LastModifiedDate.getTime()-((wNA)o).LastModifiedDate.getTime()).intValue();            
    }

    public string Type {get; set;}
    public string Id {get; set;}
    public string fileName {get; set;}
    public string createdBy {get; set;}
    public datetime LastModifiedDate {get; set;}
    public string contentType {get; set;}
    public string LastModifiedDtStr {get; set;}
}       

Here below you can see the issue:

The bottom 3 records appear to be sorted correctly, from newest to oldest...

But the top two that I added just now within 1 minute of one another are not sorted correctly by LastModifiedDate

enter image description here

The LastModifiedDate dates are:

  • Fri, 22 Jan 2016 11:01:29

and

  • Fri, 22 Jan 2016 11:01:56

So what have I missed or got wrong here? It looks like it's sorting by Type then by LastModifiedDate

How could I modify my

4
  • 1
    Problem is here - lstAttachments[iDx].LastModifiedDate.Date(). You are getting Date, which is not the same as DateTime (no time stored inside). In this case 2 first and 3 last records have the same date, which mean that they are sorted correctly. Just change lstAttachments[iDx].LastModifiedDate.Date(); to lstAttachments[iDx].LastModifiedDate;
    – kurunve
    Commented Jan 22, 2016 at 14:19
  • @kurunve: Thanks, that makes sense, please would you add that as an answer so I can mark it as the solution? Commented Jan 22, 2016 at 14:22
  • 1
    one more issue found
    – kurunve
    Commented Jan 22, 2016 at 14:33
  • funny story, can anyone see the silly error in the time part: .LastModifiedDate.format('EEE, d MMM yyyy HH:MM:ss'); - should have been .LastModifiedDate.format('EEE, d MMM yyyy HH:mm:ss'); DOH :) Commented Jan 31, 2016 at 23:00

1 Answer 1

8

Problem is here:

lstAttachments[iDx].LastModifiedDate.Date(). You are getting Date, which is not the same as DateTime (no time stored inside). In this case 2 first and 3 last records have the same date, which mean that they are sorted correctly. To fix that, lstAttachments[iDx].LastModifiedDate.Date(); needs to be replaced by lstAttachments[iDx].LastModifiedDate;

Update: one more issue found: In sorting, there may overflow appears at next line:

return -(LastModifiedDate.getTime()-((wNA)o).LastModifiedDate.getTime()).intValue();            

Problem is in converting big long numbers to integer. In case if difference between 2 dates are around 20 years - wrong sign would be returned. Next lines of code as a proof:

System.debug((DateTime.now().getTime() - DateTime.now().addDays(60000).getTime()));
System.debug((DateTime.now().getTime() - DateTime.now().addDays(60000).getTime()).intValue());

Output would be -5184000000000 and 25526272 relatively. To avoid that issue - use Math.Signum method. For example:

System.debug(Integer.valueOf(Math.signum(DateTime.now().getTime() - DateTime.now().addDays(60000).getTime())));

P.S. I know that 60000 days are ~164 years. If fails on 6000 days as well

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .