1

Really not sure where I'm going wrong here.

I have some JavaScript to sort a table by date value:

function sortByDate() {
    if (jQuery("#web-orders .data-table tbody").length > 0) {
        var tbody = document.querySelector("#web-orders .data-table tbody");
        var rows = [].slice.call(tbody.querySelectorAll("tr"));
    }
    if (jQuery("#store-orders .data-table tbody").length > 0) {
        var tbodyStore = document.querySelector("#store-orders .data-table tbody");
        var rowsStore = [].slice.call(tbodyStore.querySelectorAll("tr"));

        rowsStore.forEach(function (entry) {
            rows.push(entry);
        });
    }

    rows.sort(function (a, b) {
        console.log("a.cells[2].innerHTML = " + a.cells[2].innerHTML);
        console.log("b.cells[2].innerHTML = " + b.cells[2].innerHTML);

        a = new Date(Date.parse(a.cells[2].innerHTML));
        b = new Date(Date.parse(b.cells[2].innerHTML));

        console.log("a = " + a);
        console.log("b = " + b);

        return a - b;
    });

    rows.forEach(function (v) {
        tbody.appendChild(v); // note that .appendChild() *moves* elements
    });
}

Now here is some of the console output with the invalid dates:

a.cells[2].innerHTML = 28/11/2017 1:49:37 PM
b.cells[2].innerHTML = 5/09/2017 6:27:35 AM
a = Invalid Date
b = Tue May 09 2017 06:27:35 GMT+0930 (Cen. Australia Standard Time)
a.cells[2].innerHTML = 28/11/2017 1:49:37 PM
b.cells[2].innerHTML = 24/09/2017 6:12:48 PM
a = Invalid Date
b = Invalid Date

Does anyone know why this might be happening? It's got me stumped.

GusP
  • 2,454
  • 2
  • 23
  • 32
Web Dev Guy
  • 1,693
  • 3
  • 18
  • 42
  • 6
    If `5/09/2017` is parsed to `May 09 2017`, what do you think `28/11/2017` will be parsed to? ;) – le_m Dec 05 '17 at 23:56
  • You really can't depend on JavaScript environments to parse dates with consistency unless the dates are in a strict format. The safest thing to do is use something like Moment with your own explicit format to parse your date strings. – Pointy Dec 05 '17 at 23:58
  • 1
    @le_m Oh good lord why I did not see that is beyond me, guess I'm having one of those days. changing my date format from `dd/MM/yy ` to `MM/dd/yyyy` done the trick. Thanks :) – Web Dev Guy Dec 06 '17 at 00:43

1 Answers1

3

Date.parse uses RFC 2822 formatting and doesn't allow to specify a custom format. Though, if your input is consistently in the DD/MM/YYYY h:m:s AM/PM format, then you can use split to do the parsing yourself and manually create a Date object.

parseDate(a.cells[2].innerHTML);
parseDate(b.cells[2].innerHTML);

function parseDate(str) {
    // Split into date, time, and AM/PM
    var parts = str.split(" ");

    // Split and parse the day, month, and year
    var date = parts[0].split("/");
    var day = parseInt(date[0]);
    var month = parseInt(date[1]) - 1;
    var year = parseInt(date[2]);

    // Split and parse the hours, minutes, and seconds
    var time = parts[1].split(":");
    var hour = parseInt(time[0]);
    var minute = parseInt(time[1]);
    var second = parseInt(time[2]);

    // Add 12 hours to the time if it's in the afternoon
    if (parts[2] == "PM") { hour += 12; }

    // Build and return our Date object
    return new Date(year, month, day, hour, minute, second);
}

As others have mentioned, you can also use Moment to make things easier.

vqdave
  • 2,361
  • 1
  • 18
  • 36
  • I will play around with this when I get some spare time :) – Web Dev Guy Dec 06 '17 at 00:44
  • @WebDevGuy if it worked for you, could you mark it as accepted? – vqdave Dec 06 '17 at 01:21
  • yeah when I test it I will :) – Web Dev Guy Dec 06 '17 at 01:56
  • The assertion that "*Date.parse uses RFC 2822 formatting*" is not supported by the language specification. ISO 8601 extended format is the only format that is required to be supported, anything else is implementation dependent. There is no need to use *parseInt* on any of the values. – RobG Dec 06 '17 at 01:57