skip to Main Content

I have an array with a few objects, which is structured like this:

const combined =
{
 id: "1",
 desc: "Description One",
 start: {
         date: "2024-11-01",
        }
},
{
 id: "2",
 desc: "Description Two",
 start: {
         dateTime: "2026-08-13T17:00:00+02:00",
        }
},
{
 id: "3",
 desc: "Description Three",
 start: {
         date: "2023-03-28",
        }
},
{
 id: "4",
 desc: "Description Four",
 start: {
         dateTime: "2026-08-13T15:00:00+02:00",
        }
}

Based on different user input there either is a date date or a date with timestamp dateTime.

Now I want to sort the array based on the earliest date by using the object that exists date or dateTime.

In the given case the correct order should be:

{
 id: "3",
 desc: "Description Three",
 start: {
         date: "2023-03-28",
        }
},
{
 id: "1",
 desc: "Description One",
 start: {
         date: "2024-11-01",
        }
},
{
 id: "4",
 desc: "Description Four",
 start: {
         dateTime: "2026-08-13T15:00:00+02:00",
        }
},
{
 id: "2",
 desc: "Description Two",
 start: {
         dateTime: "2026-08-13T17:00:00+02:00",
        }
}

The earliest date is now [0] and same day dates should be sorted by earliest time.

I tried to use Array.prototype.sort(), but I guess I can’t compare the dates in that format.

2

Answers


  1. The dates are string comparable without being converted. A localeCompare is enough and you can destruct the object to get at either date or dateTime

    I STRONGLY assume same timezone, or this excercise is useless. What are the timezones supposed to be on dates without TZ?

    combined.sort((a, b) => {
      const { date: dateA, dateTime: dateTimeA } = a.start;
      const { date: dateB, dateTime: dateTimeB } = b.start;
      return (dateTimeA || dateA).localeCompare(dateTimeB || dateB);
    });
    
    console.log(combined);
    <script>
    const combined = [
      { id: "1", desc: "Description One", start: { date: "2024-11-01" } },
      { id: "2", desc: "Description Two", start: { dateTime: "2026-08-13T17:00:00+02:00" } },
      { id: "3", desc: "Description Three", start: { date: "2023-03-28" } },
      { id: "4", desc: "Description Four", start: { dateTime: "2026-08-13T15:00:00+02:00" } },
    ];
    </script>
    Login or Signup to reply.
  2. Just properly convert date strings to local timezone dates and sort.

    (as an example I’ve added 2026-08-13T16:00:00-01:00 so it would go before 2026-08-13T15:00:00+02:00).

    Regarding dates: since they don’t contain any timezone it’s assumeed they are in the local timezone:

    const getDate = src => {
      
      if(src.date){
    
        // add time to parse in local timezone
        // if you need UTC, remove the suffix
        return new Date(src.date + 'T00:00:00');
    
      }
        
      const dt = new Date(src.dateTime.slice(0,19));
    
      // extract timezone offset from the string
      const [offH, offM] = src.dateTime.slice(19).split(':');
    
      // compare to the browser timezone
      const offDiff = -dt.getTimezoneOffset() - (offH * 60 + +offM);
    
      // correct the date to the offset difference
      dt.setMinutes(dt.getMinutes() - offDiff);
    
      return dt;
    }
    
    const sorted = combined.toSorted(({start: a}, {start: b}) => getDate(a) - getDate(b));
    
    console.log(sorted);
    <script>
    const combined = [
    {
     id: "1",
     desc: "Description One",
     start: {
             date: "2024-11-01",
            }
    },
    {
     id: "2",
     desc: "Description Two",
     start: {
             dateTime: "2026-08-13T17:00:00+02:00",
            }
    },
    {
     id: "3",
     desc: "Description Three",
     start: {
             date: "2023-03-28",
            }
    },
    {
     id: "4",
     desc: "Description Four",
     start: {
             dateTime: "2026-08-13T15:00:00+02:00",
            }
    },
    {
    id: "5",
     desc: "Description Five",
     start: {
             dateTime: "2026-08-13T16:00:00-01:00",
            }
    }
    ];
    </script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search