Date Conversions in Template - French Republican Calendar

Hey There, got a weird one for everyone.

I like using the French Republican Calendar for my personal life; on my blog, dates are tagged using this format.

https://lagomor.ph

The way I do this currently is that I have the usual date in the frontmatter of my posts, and a second variable for the republican formatted date.

It feels to me that it would be possible to write a Hugo template that does this math on build. I have written client side javascript in the past that can do this conversion, but since the date of the post doesn’t change once the site is built, I would vastly prefer that this conversion only happens on build.

Any ideas how to accomplish this? Here’s example Javascript for the math required to convert between the two date formats.

const months = [
        'Vendémiaire', 'Brumaire', 'Frimaire', 'Nivôse', 'Pluviôse', 'Ventôse',
        'Messidor', 'Thermidor', 'Fructidor', 'Prairial', 'Germinal', 'Floreal'
    ];

    const sansculottides = ['Virtue', 'Genius', 'Labour', 'Opinion', 'Rewards', 'Revolution'];

function isLeapYear(year) {
        return (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) && (year % 4000 !== 0);
    }

    function toRepublicanCalendar(year, month, day) {
        let startYear = year;
        if (month < 9 || (month === 9 && day < 22)) {
            startYear--;
        }

        const startRepublican = new Date(startYear, 8, 22);
        const currentDate = new Date(year, month - 1, day);
        let dayOfYear = Math.floor((currentDate - startRepublican) / (24 * 60 * 60 * 1000));

        const daysInYear = isLeapYear(startYear) ? 366 : 365;
        if (dayOfYear >= daysInYear - 5) {
            const sansculottidesDay = dayOfYear - (daysInYear - 6);
            return { day: sansculottidesDay, month: 'Sansculottides', year: startYear - 1791 };
        }

        if (isLeapYear(startYear)) {
            dayOfYear++;
        }

        const republicanMonth = Math.floor(dayOfYear / 30);
        const republicanDay = dayOfYear % 30 + 1;
        return { day: republicanDay, month: months[republicanMonth], year: startYear - 1791 };
    }

You can use something like that in your templates:

{{ $month_names := slice "janvier" "février" "mars" "avril" "mai" "juin" "juillet" "août" "septembre" "octobre" "novembre" "décembre" }}
{{ $month := sub .Date.Month 1 }}

<time datetime="{{ .Date.Format "2006-01-02"}}">{{ .Date.Day }}{{ if eq .Date.Day 1 }}er{{end}}&nbsp;{{ index $month_names $month }} {{ .Date.Year }}</time>

But you have to add the logic between the slices and the display with templates conditions and math. So you can convert your dates in “pure Go templates style”.