Skip to content

yearsSince

My website has a few places where I share how many years have passed since something happened. For example:

Nobody has figured out how to stop time, so I needed to deal with the fact that those year numbers won’t stay accurate for very long. Here’s how I did it:

How it works

In a directory named /src/_shortcodes is a file called years-since.js:

export default function yearsSince(dateString) {

    // Is the passed-in value (dateString) really a string? Is it formatted as required?
    if (typeof dateString !== 'string' || !/^\d{4}-\d{2}-\d{2}$/.test(dateString)) {
        throw new Error('The `yearsSince` function requires a valid date string in the format "YYYY-MM-DD".');
    }
    
    // Convert dateString into a Date object.
    const startDate = new Date(dateString);
    
    // Is the new Date object (startDate) a valid, parsable date?
    if (isNaN(startDate.getTime())) {
        throw new Error(`Invalid date string passed to "yearsSince": ${dateString}`);
    }

    // Extract the year from startDate.
    const startYear = startDate.getFullYear();
    
    // Get the current date.
    const now = new Date();

    // Extract the year from the current date.
    const currentYear = now.getFullYear();

    // Calculate the difference between the current year and the start year.
    let years = currentYear - startYear;

    // Determine if the anniversary of the passed-in date has already occurred this year.
    const hasCompletedThisYear =
        now.getMonth() > startDate.getMonth() ||
        (now.getMonth() === startDate.getMonth() && now.getDate() >= startDate.getDate());

    // If the anniversary has already occurred this year, return the full number of years,
    // otherwise subtract 1 since the current year’s anniversary hasn’t been reached yet.
    return hasCompletedThisYear ? years : years - 1;

}

years-since.js is imported into the eleventy.config.js file:

// …
import YearsSince from './src/_shortcodes/years-since.js';
// …

export default async function (eleventyConfig) {
    // …
    eleventyConfig.addShortcode('yearsSince', YearsSince);
    // …
};

Finally, I use that shortcode in my content. For example:

…running The Outfit for {% yearsSince '2012-06-01' %} years and…

My JavaScript and Eleventy skills aren’t the greatest, so I welcome all feedback, criticism, etc.: marcamos@gmail.com.