1

I am not able to sort by latest date time in javascript.

Below is my json :

let jsonStr = [{id:1,date:"04/04/2017 17:47"},
               {id:2,date:"05/01/2015 12:35"},
               {id:3,date:"31/02/2017 10:00"},
               {id:4,date:"31/02/2017 12:00"}];

Expected result : Latest date time should be first in the list

  • 04/04/2017 17:47
  • 31/02/2017 12:00
  • 31/02/2017 10:00
  • 05/01/2015 12:35

Current result :

  • 31/02/2017 12:00
  • 31/02/2017 10:00
  • 04/04/2017 17:47
  • 05/01/2015 12:35

Sorting logic that I used :

function sortFunction(a,b){  
   var dateA = new Date(a.date).getTime();
   var dateB = new Date(b.date).getTime();
   return dateB > dateA ? 1 : -1; 
}; 

let jsonStr = [{id:1,date:"04/04/2017 17:47"},
               {id:2,date:"05/01/2015 12:35"},
               {id:3,date:"31/02/2017 10:00"},
               {id:4,date:"31/02/2017 12:00"}];

jsonStr.sort(sortFunction);​

Reference links that I used :

Thanks in advance.

Community
  • 1
  • 1
Siddharth_Vyas
  • 9,487
  • 10
  • 36
  • 67
  • https://codepen.io/weedenwright/pen/gkvcL – user93 Apr 05 '17 at 05:10
  • 1
    your id 3 and 4 has the wrong date that is not possible 31/02/2017 – Trimantra Software Solution Apr 05 '17 at 05:12
  • Did you check what `new Date()` gives for your strings? – Bergi Apr 05 '17 at 05:14
  • 1
    actually javascript `Date` expect format as `MM/dd/yyyy` so 3rd and 4th are invalid date and if you try to use `new Date(..)` method it will return `invalid date`, try to send the json date from your server as `MM/dd/yyy hh:mm` and the links you are referencing will work for you. – Deepak Sharma Apr 05 '17 at 05:20
  • 1
    try fiddle. https://jsfiddle.net/stdeepak22/g1tgp04h/ – Deepak Sharma Apr 05 '17 at 05:25
  • 1
    @DeepakSharma—are you sure about that? Have you checked the format [*specified in ECMA-262*](http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date-time-string-format)? – RobG Apr 05 '17 at 05:28

3 Answers3

2

It's not interpreting the date the way you think it is. For example,

console.log(new Date("05/01/2015 12:35"));

produces for me:

Date 2017-05-01T19:35:00.000Z

which shows that it's expecting the date to be in MM/dd/yyyy format.


You can either roll your own solution or use one of the libraries out there. There are a lot of solutions available. I personally like moment.js which allows date format strings.

Another example, quoted from this answer, adds date parsing format control to strings:

String.prototype.toDate = function(format)
{
  var normalized      = this.replace(/[^a-zA-Z0-9]/g, '-');
  var normalizedFormat= format.toLowerCase().replace(/[^a-zA-Z0-9]/g, '-');
  var formatItems     = normalizedFormat.split('-');
  var dateItems       = normalized.split('-');

  var monthIndex  = formatItems.indexOf("mm");
  var dayIndex    = formatItems.indexOf("dd");
  var yearIndex   = formatItems.indexOf("yyyy");
  var hourIndex     = formatItems.indexOf("hh");
  var minutesIndex  = formatItems.indexOf("ii");
  var secondsIndex  = formatItems.indexOf("ss");

  var today = new Date();

  var year  = yearIndex>-1  ? dateItems[yearIndex]    : today.getFullYear();
  var month = monthIndex>-1 ? dateItems[monthIndex]-1 : today.getMonth()-1;
  var day   = dayIndex>-1   ? dateItems[dayIndex]     : today.getDate();

  var hour    = hourIndex>-1      ? dateItems[hourIndex]    : today.getHours();
  var minute  = minutesIndex>-1   ? dateItems[minutesIndex] : today.getMinutes();
  var second  = secondsIndex>-1   ? dateItems[secondsIndex] : today.getSeconds();

  return new Date(year,month,day,hour,minute,second);
};

Example:

"22/03/2016 14:03:01".toDate("dd/mm/yyyy hh:ii:ss");
"2016-03-29 18:30:00".toDate("yyyy-mm-dd hh:ii:ss");
Community
  • 1
  • 1
Ouroborus
  • 12,316
  • 1
  • 27
  • 51
2

The first rule with dates is do not use the Date constructor (or Date.parse) to parse strings. Do it manually. A library can help, but if you only have to deal with one format, then a simple function will suffice.

You can convert the strings to a format that sorts, say ISO 8601, or convert them to dates and sort those, e.g.

var data = [{id:1,date:"04/04/2017 17:47"},
            {id:2,date:"05/01/2015 12:35"},
            {id:3,date:"31/02/2017 10:00"},
            {id:4,date:"31/02/2017 12:00"}];
            
function parseDMYhm(s) {
  var b = s.split(/\D/);
  return new Date(b[2], b[1]-1, b[2], b[3], b[4]);  
}

data.sort(function(a, b) {
  return parseDMYhm(a.date) - parseDMYhm(b.date);
});

console.log(data);

Note that the parse function does not validate the date values, so 31/02/2017 will be treated as 3 March, 2017. If you want to validate the date values, that is one more line of code.

An alternative to sort as strings might be:

var data = [{id:1,date:"04/04/2017 17:47"},
            {id:2,date:"05/01/2015 12:35"},
            {id:3,date:"31/02/2017 10:00"},
            {id:4,date:"31/02/2017 12:00"}];
            
// Reformat DD/MM/YYYY HH:mm as YYYY-MM-DDTHH-mm
function formatStringAsISO(s) {
  var b = s.split(/\D/);
  return b[2] + '-' + b[1] + '-' + b[0] + 'T' + b[3] + ':' + b[4];
}

data.sort(function(a, b) {
  return formatStringAsISO(a.date).localeCompare(formatStringAsISO(b.date));
});

console.log(data);
RobG
  • 124,520
  • 28
  • 153
  • 188
1

That is because some of your dates are returning Invalid date when put inside the date object new Date()

Eg: 31/02/2017 is not a valid date

If you enter the correct dates, it will give you the right output.

Rahul Arora
  • 4,217
  • 1
  • 14
  • 22
  • Sure it is. [Some countries write their dates with the day first](https://en.wikipedia.org/wiki/Date_format_by_country). – Ouroborus Apr 05 '17 at 05:16
  • even then thats not a valid date 31 February 2017 does not exist in the calendar and javascript will return Invalid date when processing that @Ouroborus – Rahul Arora Apr 05 '17 at 05:19
  • 1
    No, it isn't a valid date as far as you or I are concerned. But assuming the dates were formatted the way Javascript was expecting, it will make a best effort: `new Date("02/31/2000")` ends up as `Date 1900-03-03T08:00:00.000Z` for me. – Ouroborus Apr 05 '17 at 05:24
  • @RahulArora—for any format other than that specified in ECMA-262, browsers can parse strings any way they like, so 31/2/2017 may return invalid date or a Date for 3 March, 2017, or 1 July 2019. – RobG Apr 05 '17 at 05:29