Filtering content based on year in a front-end yearly archive.

8 replies
Last updated: Nov 24, 2023
I have content that have a duration (example: 2022–02–03 to 2023–01–05), how can I filter these on year? Imagine a front-end having a yearly archive, so the example should not show up if you're on
but if you're on
it should.
Nov 24, 2023, 5:45 PM
You could use the
function to split on
and get the first index:

*[_type == 'post' && string::split(date, "-")[0] == $year]

// params
  'year': '2023',
Potential downside is that the year param probably needs to be handled as a string.
Nov 24, 2023, 5:51 PM
You can also replace the
predicate with:

&& date >= "2023" && date < "2024"
This would filter the year 2023.
Nov 24, 2023, 6:00 PM
thanks for your reply geoff! I'm curious, since it's a duration rather than just a simple date:
duration:{…} 3 properties
isn't it a bit more complicated?
Nov 24, 2023, 6:04 PM
That may be different from the question I thought I was answering, which was about filtering by year, yearly archives, etc. I may have misunderstood you.
Nov 24, 2023, 6:06 PM
I think you could still use the comparison operators, but the
would be against
would be against
. Does that accomplish what you’re after?
Nov 24, 2023, 6:07 PM
  _type == 'exhibition'
 && (
  // Condition 1: Posts that started within the specified year
  (duration.start >= $startOfYear && duration.start <= $endOfYear) || 
  // Condition 2: Posts that ended within the specified year
  (duration.end >= $startOfYear && duration.end <= $endOfYear) ||
  // Condition 3: Posts that spanned the entire specified year
  (duration.start < $startOfYear && duration.end > $endOfYear)
Nov 24, 2023, 6:13 PM
chat gpt helped me out 🙂
Nov 24, 2023, 6:13 PM
GROQ string comparisons are using lexicographic ordering rules, just as in JavaScript.
That means that timestamps in the standard RFC 3339 and ISO 8601 formats, such as:

are lexicographically ordered, if they're in the same time zone.

In other words,
laterDateTime > newerDateTime
is always true. The same goes for
This is because lexicographic ordering ensures
and so on. Since such timestamps are written with the most significant part (year) first, and each part is always equally long, they are comparable:
This also means you can omit any trailing part when using
. For example,
"2023-03-02T00:00:00Z" >= "2023"
will be true, and also true for any date past the year 2023.
It seems hacky, but it actually isn't when you think about it. And it's fast. The
trick also works, but is not optimized to an efficient filter operation.
Nov 24, 2023, 8:02 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?