skip to Main Content

I know there have been a few questions similar to this but haven’t found a data structure like mine.

My array of objects

const dateAndTime = [
  {
    "createdAt": "20/02/2024, 16:13:51"
  },
  {
    "createdAt": "20/02/2024, 16:15:23"
  },
  {
    "createdAt": "18/02/2024, 14:27:31"
  },
  {
    "createdAt": "18/02/2024, 15:41:06"
  },
  {
    "createdAt": "21/03/2024, 22:09:35"
  },
  {
    "createdAt": "07/03/2024, 17:24:19"
  },
];

Here is the function I built to sort (Newest First)

 dateAndTime.sort((a, b) => {
  const dateA = new Date(a.createdAt);
  const dateB = new Date(b.createdAt);
  return dateB.getTime() - dateA.getTime();
});

console.log(dateAndTime);

OUTPUT

[
  {
    "createdAt": "20/02/2024, 16:13:51"
  },
  {
    "createdAt": "20/02/2024, 16:15:23"
  },
  {
    "createdAt": "18/02/2024, 14:27:31"
  },
  {
    "createdAt": "18/02/2024, 15:41:06"
  },
  {
    "createdAt": "21/03/2024, 22:09:35"
  },
  {
    "createdAt": "07/03/2024, 17:24:19"
  },
]

EXPECTED OUTPUT

[
  {
    "createdAt": "21/03/2024, 22:09:35"
  },
  {
    "createdAt": "07/03/2024, 17:24:19"
  },
  {
    "createdAt": "20/02/2024, 16:15:23"
  },
  {
    "createdAt": "20/02/2024, 16:13:51"
  },
  {
    "createdAt": "18/02/2024, 15:41:06"
  },
  {
    "createdAt": "18/02/2024, 14:27:31"
  },
]

As you can see, the output is pretty much the same, it doesnt seem to be sorting newest first. The expected output is newest first, so the 21st March 2024 10:09:35 PM should be the first object in the array, then it gets older from there.

Where am I going wrong here?

Many thanks in advance!

4

Answers


  1. the default JavaScript Date constructor expects a date string in a format that can be recognized by the Date.parse() method, typically in the format of "YYYY-MM-DDTHH:mm:ss.sssZ". However, the dates in your createdAt property are in the format "DD/MM/YYYY, HH:mm:ss".

    To properly parse the dates, you need to split the string and rearrange the elements to fit the expected format.

    dateAndTime.sort((a, b) => {
      const dateA = new Date(a.createdAt.split(', ')[0].split('/').reverse().join('-') + 'T' + a.createdAt.split(', ')[1]);
      const dateB = new Date(b.createdAt.split(', ')[0].split('/').reverse().join('-') + 'T' + b.createdAt.split(', ')[1]);
      return dateB.getTime() - dateA.getTime();
    });
    
    Login or Signup to reply.
  2. You will need to parse the date values into proper strings and sort by those:

    const dateAndTime = [
      {
        "createdAt": "20/02/2024, 16:13:51"
      },
      {
        "createdAt": "20/02/2024, 16:15:23"
      },
      {
        "createdAt": "18/02/2024, 14:27:31"
      },
      {
        "createdAt": "18/02/2024, 15:41:06"
      },
      {
        "createdAt": "21/03/2024, 22:09:35"
      },
      {
        "createdAt": "07/03/2024, 17:24:19"
      },
    ];
    function parseDate(dt) {
        let mainSplit = dt.split(", ");
        let yearParts = mainSplit[0].split("/");
        return `${yearParts[2]}-${yearParts[1]}-${yearParts[0]} ${mainSplit[1]}`;
    }
     dateAndTime.sort((a, b) => {
      const dateA = new Date(parseDate(a.createdAt));
      const dateB = new Date(parseDate(b.createdAt));
      return dateB - dateA;
    });
    console.log(dateAndTime);
    Login or Signup to reply.
  3. To make your life easier, try using the MomentJS or Luxon library:
    https://www.npmjs.com/package/luxon

    And for your need, use the sort or diff function like so,

    import { DateTime } from 'luxon';
    
    const dateAndTime = [
      {
        "createdAt": "20/02/2024, 16:13:51"
      },
      {
        "createdAt": "20/02/2024, 16:15:23"
      },
      {
        "createdAt": "18/02/2024, 14:27:31"
      },
      {
        "createdAt": "18/02/2024, 15:41:06"
      },
      {
        "createdAt": "21/03/2024, 22:09:35"
      },
      {
        "createdAt": "07/03/2024, 17:24:19"
      },
    ];
    
    const sortedDates = dateAndTime.sort((a, b) => {
      const dtA = DateTime.fromFormat(a.createdAt, 'dd/MM/yyyy, HH:mm:ss');
      const dtB = DateTime.fromFormat(b.createdAt, 'dd/MM/yyyy, HH:mm:ss');
      return dtA.diff(dtB).milliseconds;
    });
    
    console.log(sortedDates);
    
    Login or Signup to reply.
  4. You don’t need to parse you date strings, just compare them character by character starting with year, for that first prepare an array of indices in which order to compare the characters.

    If all of your dates in 2000x you can even skip the first 2 year chars.

    const dateAndTime=[{createdAt:"20/02/2024, 16:13:51"},{createdAt:"20/02/2024, 16:15:23"},{createdAt:"18/02/2024, 14:27:31"},{createdAt:"18/02/2024, 15:41:06"},{createdAt:"21/03/2024, 22:09:35"},{createdAt:"07/03/2024, 17:24:19"},];
    
    // 6,7,8,9 - year, 3,4 - month, 0,1 - day, the rest is time
    const indices = [6,7,8,9,3,4,0,1,12,13,15,16,18,19];
    
    dateAndTime.sort((a, b) => {
      for(const i of indices){
        const r = b.createdAt[i] - a.createdAt[i];
        if(r) return r;
      }
      return 0;
    });
    
    dateAndTime.forEach(r => console.log(JSON.stringify(r)));

    This way it will be extremely fast since you don’t do any write operations:

    ` Chrome/123
    ------------------------------------------------
    Alexander   1.00x | x1000000 526 534 535 537 546
    Lajos      15.44x |  x100000 812 821 851 856 859
    ------------------------------------------------
    https://github.com/silentmantra/benchmark `
    
    const dateAndTime=[{createdAt:"20/02/2024, 16:13:51"},{createdAt:"20/02/2024, 16:15:23"},{createdAt:"18/02/2024, 14:27:31"},{createdAt:"18/02/2024, 15:41:06"},{createdAt:"21/03/2024, 22:09:35"},{createdAt:"07/03/2024, 17:24:19"},];
    
    // @benchmark Lajos
    function parseDate(dt) {
        let mainSplit = dt.split(", ");
        let yearParts = mainSplit[0].split("/");
        return yearParts[2] + '-' + yearParts[1] + '-' + yearParts[0] + ' ' + mainSplit[1];
    }
    
    dateAndTime.toSorted((a, b) => {
      const dateA = new Date(parseDate(a.createdAt));
      const dateB = new Date(parseDate(b.createdAt));
      return dateB - dateA;
    });
    
    // @benchmark Alexander
    const indices = [6,7,8,9,3,4,0,1,12,13,15,16,18,19];
    
    dateAndTime.toSorted((a, b) => {
      for(const i of indices){
        const r = b.createdAt[i] - a.createdAt[i];
        if(r) return r;
      }
      return 0;
    });
    
    /*@skip*/ fetch('https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js').then(r => r.text().then(eval));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search