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

  • 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 Jan 22 '16 at 14:19
  • @kurunve: Thanks, that makes sense, please would you add that as an answer so I can mark it as the solution? – Our Man in Bananas Jan 22 '16 at 14:22
  • 1
    one more issue found – kurunve Jan 22 '16 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 :) – Our Man in Bananas Jan 31 '16 at 23:00
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.