Skip to main content

Command Palette

Search for a command to run...

A Pitfall: Date Sorting

Updated
3 min read

To speed up my blogging and be more honest about my learning process, I've decided to start sharing even the small (and sometimes silly) mistakes I make. Thanks for reading with kind eyes. 😅

Quick question: Can you spot what's wrong with this code?

type Data = {
  value: string;
  createdAt: string;
};

const sorted = (data as Data[]).sort((a, b) => b.createdAt - a.createdAt);

After my team asked me to use the Cursor editor, this was the code it suggested with a single Tab. I couldn't notice the mistake at first. It worked fine on my local environment, so I pushed it to the staging. Then, we noticed the sorting wasn’t working correctly. 😱

The Problem

The first thing I noticed was the cache data difference. When reloading the query, the created time cache always has a time zone. However, after overwriting the cache with subscription data, the created time doesn't have a time zone. And that is causing wrong results.

// Query data
createdAt: "2024-03-20T10:00:00+09:00"

// Subscription data
createdAt: "2024-03-20T01:00:00Z"

Most readers probably noticed that the time is actually the same. Just format is different. However, I focused too much on why the time format changed. So it took way more time to figure out.

Why Different Time Formats?

This wasn't a direct issue, but the reason for the different time formats lies in how the data is handled:

  • Subscription data comes through WebSocket connections

  • WebSocket protocols often standardize on UTC (`Z`) to avoid timezone confusion

So when I use the subscription value to update the cache, it uses UTC.

The Solution

In short, sorting with string value is the problem. (Format is not the problem)

Here's the correct way to sort date strings:

// Wrong ❌
const sorted = (data as Data[]).sort((a, b) => b.createdAt - a.createdAt);

// Right ✅
const sorted = (data as Data[]).sort(
  (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
);

Note: String Subtraction

The subtraction operator (`-`) attempts to convert strings to numbers. If both sides are strings results in NaN because these strings can't be converted to valid numbers.

console.log("5" - 3);
// Expected output: 2

console.log("hello" - "hello");
// Expected output: NaN

This raises another question: "If string subtraction results in NaN, why did it seem to work in my local environment?"

I really don't know the reason for this. Maybe it just API result was sorted as I expected... 🤷‍♀️

AI Suggestion Distraction

Another reason that I couldn't point out the problem is ... I think ... AI suggestion.

The Cursor editor is powerful — it helps me modify multiple lines with a single Tab press and automatically suggests code.

After I fixed the problem, I realized that a few lines up from the problem code, I was doing a similar sort. Which I wrote before I switched to the cursor editor. So if I was writing a code, this might not have happened.

The thing is, I probably haven’t been using it properly. That said, I don’t really have the option not to use it...

Wrap up

  1. Always Convert to Date Objects

  2. Don't rely too much on convenient features

Small bugs can sneak in easily, but I think writing about it will help me next time 😊

Resources