1

I am using react JS to fetch some data from and API endpoint and then display it. I want to sort it by date and time before displaying it. Data looks like this when it's fetched:

{
  "2021-03-09T07:47:24.897Z[UTC]": "Something happened",
  "2021-03-09T07:48:12.256Z[UTC]": "Test event",
  "2021-03-09T08:04:49.484Z[UTC]": "Warning",
  "2021-03-09T07:08:15.714Z[UTC]": "Test event 2",
  "2021-03-09T07:47:24.736Z[UTC]": "Something bad happened 2"
}

I cannot change this json structure. I need to sort this by date and time and display in this format YYYY-MM-DD h:mm:ss

My function to do this looks like this:

formatDate(obj) {
    return Object.keys(obj).sort((a,b) => moment(a.obj).format('YYYY-MM-DD h:mm:ss') - moment(b.obj).format('YYYY-MM-DD h:mm:ss'))
}

Then I do the following to the fetched json object:

console.log(this.formatDate(json));

Doing so returns the following:

0: "2021-03-09T07:47:24.897Z[UTC]"
1: "2021-03-09T07:48:12.256Z[UTC]"
2: "2021-03-09T08:04:49.484Z[UTC]"
3: "2021-03-09T07:08:15.714Z[UTC]"
4: "2021-03-09T07:47:24.736Z[UTC]"

Returned dates are not sorted. How do I make sure these returned sorted?

1
  • 1
    Object.keys(obj).sort((a,b) => new Date(a.replace("\[UTC\]", "")) - new Date(b.replace("\[UTC\]", ""))) Commented Mar 10, 2021 at 4:12

2 Answers 2

1
  1. There is no obj property in your json.
  2. There is no need to apply format, as the value becomes String. We can just compare the moment object.
  3. The "[UTC]" inside the key is not standard date format, which leads to warning

Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.

You may try following snippet which fix above points:

$(function () {
  
  let json = {
  "2021-03-09T07:47:24.897Z[UTC]": "Something happened",
  "2021-03-09T07:48:12.256Z[UTC]": "Test event",
  "2021-03-09T08:04:49.484Z[UTC]": "Warning",
  "2021-03-09T07:08:15.714Z[UTC]": "Test event 2",
  "2021-03-09T07:47:24.736Z[UTC]": "Something bad happened 2"
  };
  console.log("Sorted result:");
  console.log(formatDate(json));
});
// better to name it as sortDate
function formatDate(obj) {
    return Object.keys(obj).sort((a,b) => moment(a.replace("\[UTC\]","")) - moment(b.replace("\[UTC\]","")));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

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

1 Comment

Funny thing is I kept looking at this [UTC] bit and it never occurred to me that's not a standard UTC date. I knew it wasn't but I never thought of removing it. Thanks a lot, I used your suggestion to solve this.
1

It's unclear by your function if you want to format a date, or sort it like your question asks, but you can directly compare datetime strings for the sorting, i.e. dateA.localeCompare(dateB).

Object.fromEntries(
  Object.entries(data).sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
);

Convert the object into an array of key-value pairs and sort the array by the key values, then convert the array of key-value pairs back into an object.

If you need to do any format conversions then you should do this via a map operation, i.e. you map an array of keys from one format to another.

To convert to a UTC time:

moment.utc(key.replace("[UTC]", "")).format('YYYY-MM-DD h:mm:ss')

const data = {
  "2021-03-09T07:47:24.897Z[UTC]": "Something happened",
  "2021-03-09T07:48:12.256Z[UTC]": "Test event",
  "2021-03-09T08:04:49.484Z[UTC]": "Warning",
  "2021-03-09T07:08:15.714Z[UTC]": "Test event 2",
  "2021-03-09T07:47:24.736Z[UTC]": "Something bad happened 2"
};

const sortedData = Object.fromEntries(
  Object.entries(data).sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
);

console.log(sortedData);

const mappedData = Object.fromEntries(
  Object.entries(sortedData).map(([key, value]) => [
    moment.parseZone(key.replace("[UTC]", "")).format('YYYY-MM-DD h:mm:ss'),
    value
  ])
);

console.log(mappedData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

2 Comments

You're right, I might have described the issue wrong. I want to sort and change the format but the issue I was having was with sorting only. I got it working now. Thanks for your input mate.
@davidb I was editing right as you must've been reviewing. MomentJS doesn't handle time zones well, and I was adding in the date format mapping. Should help clarify a bit more. Cheers.

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.