How to Sort by Date if my date fields are not formatted as Dates

I have a site that I am porting over from badly coded PHP to Jekyll. My site has a YML data file like _data/comments.yml that I use to store comments. The legacy site didn’t store the date for comments for some time and then started to store the date later, so my entries are mixed. And as I understand it, the dates are not well formatted so they are being treated like strings. Here is an example:

- property: a-url-slug
  person: 'This guy'
  date: 'Mar 23, 2020'
  comment: 'A comment'
- property: a-different-url-slug
  person: 'Another guy'
  date: ''
  comment: 'A comment'

My query to get everything out of this data file right now is this:

{% assign comments = site.data.comments | orderby: 'date' %}

But the order that items come back in is mixed, like this:

Bob Zampini – June 29, 2010
Jim Kelly – May 22, 2008
Mike Blake – 
Bob Renell – 
Robert Yarbrough – May 4, 2018
Pete F. – March 2, 2016
Ernie Hanson – November 6, 2015

This seems to be because the date in my YML is not stored as a proper machine readable date. It’s readable and parsable when using date filters, which work on well-formatted strings, but the date is not an object that a query will reliably sort on.

My question, finally, is how can I pre-filter or pre-convert the dates in my legacy content into machine-readable well-formatted date objects? Do I need to handwrite or parse with some other method these poorly formed dates into ISO dates? Can a plugin help me query on poorly formed date strings? Or is there another way for me to get the data out of my YML file when performing a query that I am not considering?

I see your problem.

According to liquid docs, jekyll will figure out your relatively clean “Mar 16, 2020” style date if you parse it through this filter:

{{ my_date | date: "%Y-%m-%d }}

Result '2020-03-16'

Unfortunately I can’t see a way to format the date and sort by it in one go.

Also by the way I’m seeing sort and sometimes sort_by so try those instead. I don’t see anyone using orderby.

I don’t know if you looked at docs or stackoverflow links but it helps to check first and post and research you found here

I found this while looking to sort by long date in jekyll.

You’re going to need to create a plugin in your repo and call it.

The problem is the same as yours except they have date as d/m/y but here is the original answer copied.

# _plugins/filters.rb
module Jekyll
  module DateFilter
    require 'date'
    def date_sort(collection)
      collection.sort_by do |el|
        Date.parse(el.data['date'], '%d-%m-%Y')
      end
    end
  end
end
Liquid::Template.register_filter(Jekyll::DateFilter)

Used like so:

{% assign sortedResources = site.resources | date_sort | reverse %}
{% for resource in sortedResources %}
  <div>{{resource.title}}</div>

Your format will be

%B %-d, %Y

Based on https://learn.cloudcannon.com/jekyll/date-formatting/

If Mar and March inconsistency causes issues you can try use %b instead of %B.

Or do a find and replace in your IDE for - November with - Nov for example. Note that going the other way will end up with NovNovember unless you are careful about adding trailing space to both sides.

I did run into that StackOverflow question and tried it but I have no experience with custom filters. I ran into this error in the console as I have run into with your example:

Error: undefined method `data' for #<Hash:0x007f859f5e9d78>

I’m stuck here so that’s part of the reason why I decided to ask the question here… to see if I needed to learn how Ruby works so I can fix the filter or if there was another way.

Thanks for the thorough response.

Using this plugin, but it is being applied to a data YML file in Jekyll and I wonder if that is why I am getting the above error. Anyone know how I might change the plug in code to apply this to a data file instead of a collection?

module Jekyll
  module DateFilter
    require 'date'
    def date_sort(collection)
      collection.sort_by do |el|
        Date.parse(el.data['date'], '%b %-d %Y')
      end
    end
  end
end
Liquid::Template.register_filter(Jekyll::DateFilter)

The error again is:

Error: undefined method `data' for #<Hash:0x007f859f5e9d78>

Being applied this way:

{%- assign comments = site.data.comments | sort date_sort -%}

el is a hash so attributes are not using dot syntax.

Try

el['data']['date']

Add debug lines before it

puts el
puts el.keys
puts el['data']

Thank you @MichaelCurrin, that was great.

In the end, since I am at the beginning of this project, I reformatted 200 or so dates to be in the yyyy-mm-dd format and that makes my Liquid sort work as intended. This plugin was an attempt to avoid reformatting legacy data, but I think in the long run it is in my best interest to start that process now.