valentyn
valentyn

Reputation: 41

Sort Dates in Javascript in format dd/mm/yyyy

I have a little problem with function sort date. I want to sort the all dates by ASC or DESC but it's not sorting correctly.

My dates

let a = [
    "03/12/2019", "17/10/2020", "02/12/2019", "08/12/2019", "13/02/2020", 
    "23/03/2020", "18/11/2020", "29/02/2020", "05/12/2019", "03/06/2020",
    "06/05/2020", "09/09/2020", "28/10/2020", "07/04/2020", "27/04/2020",
    "28/05/2020", "29/12/2019", "31/10/2020", "23/09/2020", "25/12/2019",
    "14/01/2020", "30/09/2020", "18/05/2020", "14/06/2020", "25/04/2020",
    "19/08/2020", "26/03/2020", "19/05/2020", "15/03/2020", "11/10/2020",
    "25/04/2020", "16/12/2019", "14/08/2020", "19/08/2020", "28/02/2020",
    "01/01/2020", "07/06/2020", "17/11/2020", "22/05/2020", "31/07/2020",
    "20/01/2020", "07/02/2020", "18/08/2020", "16/02/2020", "13/03/2020",
    "21/12/2019", "02/03/2020", "24/07/2020", "01/05/2020", "31/01/2020",
    "25/11/2020", "07/07/2020", "16/07/2020", "06/07/2020", "16/09/2020",
    "29/07/2020", "19/06/2020", "09/08/2020", "25/08/2020", "21/02/2020",
    "30/11/2019", "04/06/2020", "06/09/2020", "10/09/2020", "26/11/2020",
    "22/07/2020", "21/05/2020", "25/07/2020", "05/01/2020", "17/06/2020",
    "14/07/2020"
];

Function sort

b.sort((d1, d2) => new Date(d1).getTime() - new Date(d2).getTime());

or alternative

b.sort((b, a) => {
 if (b > a) {
   return 1;
 }
 if (b < a) {
   return -1;
 }
 return 0;
})

Upvotes: 1

Views: 1859

Answers (3)

Lauren de Loxeley
Lauren de Loxeley

Reputation: 11

const sortDate = (date1,date2) => {
const a = date1.split("/").map((i) => parseInt(i));
const b = date2.split("/").map((i) => parseInt(i));
return a[2] > b[2]
  ? 1
  : a[2] < b[2]
  ? -1
  : a[1] > b[1]
  ? 1
  : a[1] < b[1]
  ? -1
  : a[0] > b[0]
  ? 1
  : a[0] < b[0]
  ? -1
  : -1;
};

Call

sortDate("01/11/2011","23/02/2010"); //returns 1

Returns 1 if date1 is greater. Returns -1 if date2 is greater.

Upvotes: 0

Dai
Dai

Reputation: 155428

Never use the new Date(string) constructor nor Date.parse() to parse a date string as neither method lets you supply a specific format or locale information. (Annoyingly, JavaScript's built-in Intl does not support parsing, only formatting).

JavaScript's new Date(string) and Date.parse(string) functions use tend to use the user's computer's regional settings to parse a date - if a user is using Windows' en-US settings without realising it then Date.parse(string) and new Date(string) will interpret dates as MM/dd/yyyy instead of their correct regional settings. However browsers tend to try to parse anything you throw at them and if they see 12/31/2019 or 31/12/2019 then they'll both be parsed as 2019-12-31 regardless of their computer regional settings - things only fall-apart if they're given 5/7/2019, for example which will be interpreted as 2019-05-07 if they're in the US or 2019-07-05 if they're in the UK.

Unfortunately you'll need to parse them manually or use a peer-reviewed library like Moment.JS (because writing date libraries is hard).

let dates = [ "03/12/2019", "17/10/2020", "02/12/2019", ... ];

function parseDate( ddMMyyyy ) {

    const components = ddMMyyyy.split( '/' );
    if( components.length != 3 ) return null; 

    const dd   = parseInt( components[0] );
    const MM   = parseInt( components[1] );
    const yyyy = parseInt( components[2] );

    // Component range checking:
    if( dd >= 1 && dd <= 31 && MM >= 1 && MM <= 12 && yyyy >= 0 && yyyy <= 9999 ) {
        return new Date( yyyy, MM - 1, dd ); // `MM - 1` because JavaScript months are 0-based.
    } 
    else {
        return null;
    }
}

let sortedParsedDates = dates
    .map( parseDate )
    .filter( dt => dt instanceof Date )
    .sort( ( x, y ) => x.getTime() - y.getTime() );

Upvotes: 3

Almatrass
Almatrass

Reputation: 125

It's because the dates are in UK format, so it'll order them by ascending day, regardless of the month or year. If you convert them to YYYY-MM-DD format it'll sort them correctly for you:

let a = ["03/12/2019", "17/10/2020", "02/12/2019", "08/12/2019", "13/02/2020"]; // etc.

function ukToUsDate(ukDate) {
  let dateArr = ukDate.split('/');

  return `${dateArr[2]}-${dateArr[1]}-${dateArr[0]}`;
}

for (let i = 0; i < a.length; i++) {
  a[i] = ukToUsDate(a[i]);
}

a.sort((b, a) => {
 if (b > a) {
   return 1;
 }
 if (b < a) {
   return -1;
 }
 return 0;
});

Upvotes: 1

Related Questions