Home > Net >  JavaScript how to sort date by most recent first
JavaScript how to sort date by most recent first

Time:01-10

I am trying to sort JSON objects received from an API so that the most recent datetime is shown first. But the way I am currently doing it is sorting Dec 2022 as more recent than Jan 2023.

Here is what I'm working with currently:

result = [
{
   "date": "21/12/2022",
    "time": "10:41:10",
},
{
    "date": "20/12/2022",
    "time": "12:42:21",
},
{
    "date": "15/12/2022",
    "time": "09:26:02",
},
{
    "date": "14/12/2022",
    "time": "10:20:54",
},
{
    "date": "09/01/2023",
    "time": "18:58:17",
},
{
    "date": "09/01/2023",
    "time": "18:57:34",
},  
{
    "date": "08/01/2023",
    "time": "12:12:38",
}]

if (result.length > 1) {
        result.sort((a, b) => {
            const dateTime1 = new Date(a.date   a.time);
            const dateTime2 = new Date(b.date   b.time);

            return dateTime2 - dateTime1;
        });

        console.log(result);
};

Which gives me:

{date: "21/12/2022", time: "10:41:10...}
{date: "20/12/2022", time: "12:42:21...}
{date: "15/12/2022", time: "09:26:02...}
{date: "14/12/2022", time: "10:20:54...}
{date: "09/01/2023", time: "18:58:17...}
{date: "09/01/2023", time: "18:57:34...}
{date: "08/01/2023", time: "12:12:38...}

How can I sort this in a way that it doesn't think 2022 is more recent than 2023?

CodePudding user response:

Issue with your code is date creation.

You can use following snippet to create date as date constructor does not accept DD/MM/YYYY.

const createDate = (d, t) => {
  const [date, month, year] = d.split('/')
  const [hours, mins, secs] = t.split(':')
  return new Date(year, month - 1, date, hours, mins, secs)
}

Also, a.date a.time is incorrect. You are concatinating both but without space. So following will be the output:

Date: "21/12/2022"
Time: "10:41:10"
Output: "21/12/202210:41:10"

Following is a working example

result = [{
    "date": "21/12/2022",
    "time": "10:41:10",
  },
  {
    "date": "20/12/2022",
    "time": "12:42:21",
  },
  {
    "date": "15/12/2022",
    "time": "09:26:02",
  },
  {
    "date": "14/12/2022",
    "time": "10:20:54",
  },
  {
    "date": "09/01/2023",
    "time": "18:58:17",
  },
  {
    "date": "09/01/2023",
    "time": "18:57:34",
  },
  {
    "date": "08/01/2023",
    "time": "12:12:38",
  }
]

const createDate = (d, t) => {
  const [date, month, year] = d.split('/')
  const [hours, mins, secs] = t.split(':')
  return new Date(year, month - 1, date, hours, mins, secs)
}

if (result.length > 1) {
  result.sort((a, b) => {
    const dateTime1 = createDate(a.date, a.time);
    const dateTime2 = createDate(b.date, b.time);
    return dateTime2 - dateTime1;
  });

  console.log(result);
};


As correctly mentioned by @RobG

That should be new Date(year, month - 1, date, hours, mins, secs), but for sorting it won't matter if all months are 1.

CodePudding user response:

You can convert your date and time in YYYY-MM-DD HH:MM:SS format and then lexicographically sort it.

const arr = [ { "date": "21/12/2022", "time": "10:41:10", }, { "date": "20/12/2022", "time": "12:42:21", }, { "date": "15/12/2022", "time": "09:26:02", }, { "date": "14/12/2022", "time": "10:20:54", }, { "date": "09/01/2023", "time": "18:58:17", }, { "date": "09/01/2023","time": "18:57:34", }, { "date": "08/01/2023", "time": "12:12:38", }],
    sorted = arr.map(o => [o, o.date.split('/').reverse().join('-')   '_'   o.time])
               .sort((a, b) => b[1].localeCompare(a[1]))
               .map(([o]) => o);
console.log(sorted);
.as-console-wrapper { max-height: 100% !important; top: 0; }

  • Related