
# How do I sort on a Calendar field?

> Calendar values are MM-dd-yyyy strings, so build a lookup table of numeric timestamps and sort on that instead.

URL: https://www.hannonhill.com/cascadecms/latest/articles/developing-in-cascade/script-formats/sort-on-calendar-field.html
category: Developing in Cascade
article-type: how-to
content-kind: faq
release-availability: all
tags: velocity, dates, query-tool
updated: 2026-10-06

A Calendar field's value, distinct from a Date/Time field, is formatted `MM-dd-yyyy`. Sorting on that string directly doesn't work, so convert it to a numeric timestamp first and sort on a lookup table.

## With the XPath Tool

```velocity
#set ($pages = $_XPathTool.selectNodes($contentRoot, "/system-index-block/system-page[​system-data-structure[calendar-field != '/']]"))

#if ($pages.size() > 0)
    #set ($lookupTable = [])

    #foreach ($p in $pages)
        #set ($date = $_DateTool.toDate("MM-dd-yyyy", $p.getChild("system-data-structure").getChild("calendar-field").value))
        #set ($dateTimestamp = $date.getTime())
        #set ($_void = $lookupTable.add({
          "timestamp": $_MathTool.mul($dateTimestamp, 1),
          "page": $p
        }))
    #end

    #foreach ($page in $_SortTool.sort($lookupTable, ["timestamp:desc"]))
        #set ($timeStamp = $page.get("timestamp"))
        #set ($item = $page.get("page"))
        #set ($itemDate = $_EscapeTool.xml($item.getChild("system-data-structure").getChild("calendar-field").value))
        #set ($dateFormat = $_DateTool.getDateFormat("MM-dd-yyyy", $_DateTool.getLocale(), $_DateTool.getTimeZone()))
        #set ($itemDate = $dateFormat.parse($itemDate))
        #set ($itemTitle = $_EscapeTool.xml($item.getChild("title").value))

        $_DateTool.format('MM/dd/yyyy', $itemDate) - ${timeStamp} - $itemTitle
    #end
#end
```

## With the Cascade API

```velocity
#set ($pages = $_.query().byContentType("path/to/Content Type").execute())
#set ($removed = $_ListTool.removeNull($pages, "structuredDataNode(calendar-field).textValue"))

#if ($pages.size() > 0)
    #set ($lookupTable = [])

    #foreach ($p in $pages)
        #set ($date = $_DateTool.toDate("MM-dd-yyyy", $p.getStructuredDataNode("calendar-field").textValue))
        #set ($dateTimestamp = $date.getTime())
        #set ($_void = $lookupTable.add({
          "timestamp": $_MathTool.mul($dateTimestamp, 1),
          "page": $p
        }))
    #end

    #foreach ($page in $_SortTool.sort($lookupTable, ["timestamp:desc"]))
        #set ($timeStamp = $page.get("timestamp"))
        #set ($item = $page.get("page"))

        $item.getStructuredDataNode("calendar-field").textValue - ${timeStamp} - $item.metadata.title
    #end
#end
```

Note the `removeNull` call in the API example — pages without a Calendar value would otherwise break the sort. See [Comparison method violates its general contract](https://www.hannonhill.com/cascadecms/latest/articles/cascade-administration/errors/comparison-method-violates-its-general-contract.html) for what that failure looks like.
