Ruby Date Parsing Shenanigans

Getting over a creative slump, fun Ruby Date quirks, and the usual cool stuff around the web

I've been in a creative slump this week. There hasn't been a particular topic I wanted to write about. When I'm in a slump I usually need to sleep, read, or build more to get out of it.

So I spent the majority of yesterday coding to see if it would trigger a topic. And I came across some Ruby Date parsing shenanigans I wanted to share with you!

In Ruby, Date.parse converts a string into a date object. I was using it to convert an input from a form to a date object I could use elsewhere. For example:

Date.parse("2025-05-22")
# => Thu, 22 May 2025

Could we use Date.parse to validate strings? I would assume Date.parse would error given an invalid string. And it does!

Date.parse("1234")
# 'Date.parse': invalid date (Date::Error)

How about the string 12345?

Date.parse("12345")
# => Mon, 10 Dec 2012

Wait what? Isn't 12345 just as invalid as 1234?

It turns out Date.parse does some funky stuff under the hood. Based on the string length, from 2 digits up to 14, it will perform different regex matches. Assigning the match to specific date labels.

2025-05-22 is a simple one; 2025 is matched to a year. 05 is matched to a month. And 22 is matched to day of month.

What about our "invalid" strings?

Since 1234 is 4 characters, it gets split into two components. 12 is the month, and 34 is the day of the month. Since there aren't 34 days in December, Date parse fails.

And 12345 being 5 characters will have different labels assigned to the numbers. 12 is matched to the year (2012) and 345 is matched to the day in the year. Giving 10 Dec 2012.

Interestingly, 69123 returns 03 May 1969. Two char digits 69-99 refer to years in the twentieth century (1969-1999). While values in the range 00-68 refer to years in the twenty-first century (2000-2068). Maybe this is common knowledge, but it wasn't to me!

So what are the lessons here?

Don't be afraid to read the source code. I used an LLM to help navigate the Ruby source code, feeding it snippets and asking questions to understand what the hell was happening.

More importantly, don't use Date.parse to validate strings! The docs do say that Date.parse results could be unpredictable. I should've listened.

Cool stuff on the web

SOLID: Interface Segregation Principle (ISP) the penultimate post in the series by Jamie Schembri. It's a well explained post on ISP and a good refresher on SOLID principles.

Obsidian will soon have databases (open to early access users)! I'm itching to try my hand at building some sort of content pipeline or link aggregator with bases.

My morning writing practice a note by Andy Matuschak. When Matuschak's writing inbox doesn't yield fruitful topics, they need to vary their inputs, or give themselves more creative space.

Thanks for reading this week's newsletter. If you have any thoughts or questions, feel free to reach out by replying to this email or send me a DM on Bluesky.

I'll be away on vacation for the next two weeks so I'll catch you all in June!

Jono