Throwback Thursday: November 7, 2024
Follow along to see how I used Test-Driven Development to replace hard-coded holiday dates with a robust, history-aware date engine in today's edition of Throwback Thursday.
With over a million words scattered across more than 1,300 articles on this blog, you've probably missed a few things here.
That’s why each week in "Throwback Thursday," we’ll revisit some standout posts. Expect a blend of my personal favorites, insightful articles from other great minds, and a touch of coding humor to keep things light.
Highlights from NoLongerSet.com
Few programming challenges expose the gap between "simple requirement" and "complete solution" quite like calculating business days.
My journey began with a practical but limited approach: scraping federal holiday dates from the U.S. Office of Personnel Management website. While this worked for dates between 1997 and 2030, it wasn't a sustainable solution. However, this initial implementation provided something invaluable - a comprehensive test suite for validating a more robust solution.
Test-Driven Development proved to be the perfect methodology for this challenge.
Using the brute-force implementation as a reliable baseline for comparison, I built a collection of tests to ensure the new function matched the existing one date-for-date. This safety net allowed me to gradually craft a more sophisticated solution that calculated holiday dates based on their legal definitions rather than relying on hard-coded values.
The true value of this approach became apparent in 2021.
When Juneteenth became a federal holiday, the calculated approach made it trivial to add support–we simply needed to add the new holiday definition and its effective date. The function even handles historical oddities, like Veterans Day being observed on the fourth Monday in October from 1971 to 1977.
This pattern extends far beyond U.S. federal holidays.
While the specific holiday calculations will differ for readers outside the United States, the underlying approach remains powerful: start with a known-good implementation, build a comprehensive test suite, then use those tests to guide the development of a more robust solution. Whether you're calculating German bank holidays or Japanese corporate observances, the pattern holds true.
Software development is often about finding the right balance between immediate needs and long-term maintainability.
Acknowledgements
- Article excerpt generated with the help of Claude-3.5-Sonnet
- Initial draft generated with the help of Claude-3.5-Sonnet
- Cover image generated by Ideogram