7

I have an array of objects like so :

var example = [{
  "description": "aaa",
  "time": "12:15pm"
}, {
  "description": "bbb",
  "time": "10:10am"
}, {
  "description": "ccc",
  "time": "4:00pm"
}, {
  "description": "ddd",
  "time": "6:15pm"
}, {
  "description": "eee",
  "time": "1:10am"
}, {
  "description": "fff",
  "time": "5:00pm"
} ];

I want to sort by the time value.

I have tried to apply this solution which was intended for an array of string values:

example.sort(function (a, b) {
  return new Date('1970/01/01 ' + a.time) - new Date('1970/01/01 ' + b.time);
});

console.log(example);

I've also been referring to the Mozilla Array.prototype.sort() documentation and tried the following which didn't seem to work:

example.sort(function(a, b) {
  if (new Date(a.time) > new Date(b.time)) {
    return 1;
  }
  if (new Date(a.time) < new Date(b.time)) {
    return -1;
  }
  // a must be equal to b
  return 0;
});

console.log(example);
3
  • 1
    Your issue is that is not a valid date format to be parsed. Commented Jun 8, 2016 at 12:46
  • 1
    new Date("1:10am"); //Invalid Date Commented Jun 8, 2016 at 12:48
  • I will try with space before am/pm suffix. Commented Jun 8, 2016 at 12:48

4 Answers 4

8

The date string that you are generating is not valid so it will always returns current date and time. So generate valid date string(eg : '1970/01/01 9:34:48 AM') then parse and return the difference. Here String#slice() method can be used to generate the valid date string.

var example = [{
  "description": "aaa",
  "time": "12:15pm"
}, {
  "description": "bbb",
  "time": "10:10am"
}, {
  "description": "ccc",
  "time": "4:00pm"
}, {
  "description": "ddd",
  "time": "6:15pm"
}, {
  "description": "eee",
  "time": "1:10am"
}, {
  "description": "fff",
  "time": "5:00pm"
}];

example.sort(function(a, b) {
  // get time from string 
  // then get am or pm from string and append
  // both can be done using the slice method
  return Date.parse('1970/01/01 ' + a.time.slice(0, -2) + ' ' + a.time.slice(-2)) - Date.parse('1970/01/01 ' + b.time.slice(0, -2) + ' ' + b.time.slice(-2))
});

console.log(example);

Sign up to request clarification or add additional context in comments.

Comments

1

You need a space before am/pm to make valid date .

We can put it in sort method before comparing as below.

example.sort(function(a,b){
  return new Date('1970/01/01 ' + a.time.replace(/(am|pm)/,' $1'))
 - new Date('1970/01/01 ' + b.time.replace(/(am|pm)/,' $1'))
})

Comments

0

You can try to calculate value in 24hr format and sort it accordingly.

Logic:

  1. Check if pm exists in string
  2. If yes and hour is not 12, add 12 to it
  3. Else return the number

var example=[{description:"aaa",time:"12:15pm"},{description:"bbb",time:"10:10am"},{description:"ccc",time:"4:00pm"},{description:"ddd",time:"6:15pm"},{description:"eee",time:"1:10am"},{description:"fff",time:"5:00pm"}];

example.sort(function(a,b){
  var t1 = get24HrFormat(a.time);
  var t2 = get24HrFormat(b.time);
  return t1>t2 ? 1 : t1<t2 ? -1 : 0;
});

function get24HrFormat(str){
  var _t = str.split(/[^0-9]/g);
  _t[0] =+_t[0] + (str.indexOf("pm")>-1 && +_t[0]!==12 ? 12: 0);
  return _t.join("");
}
  
document.write("<pre>" + JSON.stringify(example,0,4)+ "</pre>")

Comments

0

If you convert your time to hours and minutes (hours should be in 24-hour format) you don't even need to use the Date constructor.

Something like this:

example.map(c => {
  var time = c.time.substring(0,c.time.length - 2);
  var am_pm = c.time.slice(-2);

  var hours = parseInt(time.split(':')[0]);
  var minutes = parseInt(time.split(':')[1]);

  if (hours === 12 && am_pm.toLowerCase() === 'am') {
    hours = 0;
  } else if (hours < 12 && am_pm.toLowerCase() === 'pm') {
    hours += 12;
  }

  // save hours and minutes
  c.hours = hours;
  c.minutes = minutes;

  return c;
}).sort((a,b) => {
  return (a.hours * 100 + a.minutes) - (b.hours * 100 + b.minutes); 
});

Note, this modifies the examples array by adding hours and minutes properties.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.