Changing a background depending on the current date with js?

hi there!!

i want the background image of one of my pages to change depending on the current date (so that it changes with the season, like green grass in summer and snow in winter). i know how to do the changing background part but not the date comparison part

all the bits of solution i seem to be finding online are either for a specific period of time that doesnt repeat (it wouldnt work here cause i dont wanna have to edit the page every year to keep it working) or are based on the month only (so like december to february instead of december 11 to february 25 like i want)

if anyone has any idea how to make this work id appreciate it because im really struggling

Oops I shouldve read your whole question!

The easiest way I would do this is by simply comparing dates.

const moonLanding = new Date("July 20, 2025");
const highdate = new Date("July 21, 2025");
console.log(moonLanding.getDate());
console.log(highdate < moonLanding);

Since the highdate date falls after the moonlanding date, doing that < comparison will return false. (Think of it like “is highdate before moonLanding?”)

You shouls be able do that with your dates! Off the top of my head there might be some other issues with the code I threw up there, but comparing dates is definitely the way I’d go

1 Like

If you do want to incorporate the day, you could set up a dictionary that stores the season boundaries.

const currentDate = new Date();
const currentYear = currentDate.getFullYear();

let goodEnoughSeasons={};

goodEnoughSeasons["spring"] = new Date(currentYear, 2, 20);
goodEnoughSeasons["summer"] = new Date(currentYear, 5, 21);
goodEnoughSeasons["fall"] = new Date(currentYear, 8, 21);
goodEnoughSeasons["winter"] = new Date(currentYear, 11, 21);

That wouldn’t be 100% accurate since the solstices and equinoxes change from year to year, but it’s simple and at worst is off by a day every now and then.

Then you could have a function that determines the season based on the date:

function getSeason(date){
    // winter - before the start of spring or after the start of winter
    if (date < goodEnoughSeasons["spring"] || date >= goodEnoughSeasons["winter"]) {
        return "winter";
    }
    // spring - between the start of spring and the start of summer
    if (date >= goodEnoughSeasons["spring"] && date < goodEnoughSeasons["summer"]) {
        return "spring";
    }
    // summer - between the start of summer and the start of fall
    if (date >= goodEnoughSeasons["summer"] && date < goodEnoughSeasons["fall"]) {
        return "summer";
    }
    // fall - between the start of fall and the start of winter
    if (date >= goodEnoughSeasons["fall"] && date < goodEnoughSeasons["winter"]) {
        return "fall";
    }
}

Here’s a little test function with a date for each season. I used March 19 and 20 to show the change from winter to spring.

function testDates(){
    const winterDate = new Date(currentYear, 2, 19);
    const springDate = new Date(currentYear, 2, 20);
    const summerDate = new Date(currentYear, 7, 10);
    const fallDate = new Date(currentYear, 9, 31);

    console.log(winterDate.toLocaleDateString() + ': ' + getSeason(winterDate));
    console.log(springDate.toLocaleDateString() + ': ' + getSeason(springDate));
    console.log(summerDate.toLocaleDateString() + ': ' + getSeason(summerDate));
    console.log(fallDate.toLocaleDateString() + ': ' + getSeason(fallDate));
}

and here’s the output:

❯ node main.js
3/19/2025: winter
3/20/2025: spring
8/10/2025: summer
10/31/2025: fall
5 Likes

I suggest doing it in a more “data driven” way so it’s easier to add more dates later.

*edit to fix mod behavior and off-by-one error

*edit it is simpler with the at method

*edit remove JAN 1 from the example so the wrap-around is clearer

// define schedule
imgSchedule = [
  ["JAN 8", "/d-img/b.jpg"],
  ["MAR 5", "/d-img/c.jpg"],
  ["JUL 11", "/d-img/d.jpg"],
  ["OCT 8", "/d-img/e.jpg"],
  ["DEC 4", "/d-img/a.jpg"],
]

// parse dates, set each to current year
imgSchedule = imgSchedule.map((tup) => [ 
  new Date((new Date(tup[0])).setFullYear(new Date().getFullYear())), tup[1] 
])

// stick a flag in the array and sort it by date
todaySymbol = Symbol("today")
imgSchedule.push([new Date(), todaySymbol])
imgSchedule.sort((a,b) => a[0] - b[0])

// find the entry in the sorted array before the flag
chosenImage = imgSchedule.at((imgSchedule.findIndex((i) => i[1] == todaySymbol) - 1))[1]

// set src of the image
document.getElementById("todaypic").src = chosenImage;
2 Likes

Not really what you asked, but another, arguably simpler way to handle this (depending on your setup) would be to use PHP to add a class tag to the body of the page, then vary the background by class in your style sheet. So in your HTML, you’d have something like

<body class="<?php echo date('M') ?>">

Then, in your stylesheet, you’d have class tags for each month (in three-letter format), each specifying a different background image, like:

.Jun { background-image: url('/burrito.jpg'); }

1 Like

i understand php even less than Javascript so i dont really wanna mess with it but good to know if i ever wanna get into php

also i was gonna test out the solutions everyone else gave but my computer died so i can’t rn sorry :pensive_face:

SeasonJS is a JavaScript library specifically for outputting the current season according to the client.

This may be a good foundation if you didn’t want to dig too deeply into code.

(sigh) I love how things that I bookmarked years ago get broken or otherwise deleted and how sharing broken/deleted things makes me look like an insensitive idiot.

My apologies for the above post. That library appears to have been canned.

Have you made any headway on this?

unfortunately my computer is broken for good so i cant test anything :pensive: i ordered what i need to fix it yesterday and im hoping to have it back in working order in a week or so

I hope you don’t mind me bumping this, I just like writing JavaScript. It’s not intended as a commentary on any previous solutions. Good luck fixing your computer!

// Background images in ascending MM/DD order
const backgrounds = [
    ['01/08', 'b.jpg'],
    ['03/05', 'c.jpg'],
    ['07/11', 'd.jpg'],
    ['10/08', 'e.jpg'],
    ['12/04', 'a.jpg'],
];

// Get today's date as MM/DD string
const today = new Date();
const options = {month: '2-digit', day: '2-digit'};
const mmdd = Intl.DateTimeFormat('en-US', options).format(today);

// Find index of latest background (might be -1)
let i = backgrounds.length;
while (--i >= 0 && backgrounds[i][0] > mmdd);

// Set background image on <body>
document.body.style.backgroundImage = `url(${backgrounds.at(i)[1]})`;

i was about to say i used your solution and it works fine but for some reason it works in vscode but not on my website??? as you can see here it only gives me the december 11-february 25 color instead of the color its actually supposed to be today

It works on my machine with chromium, but


Firefox gets a different result:

Adding some “watch expressions” in the debugger in Firefox we can see that the dates weren’t parsed correctly there.

Testing some dates in the console, it seems Firefox is a bit more picky about parsing dates.

So add a year to each of the dates and it should be ok.

Alternately, you could keep the dates the same in the array and tack on an extra 0 in code just before it gets parsed:

// parse dates, set each to current year
imgSchedule = imgSchedule.map((tup) => [ 
  new Date((new Date(tup[0]+" 0")).setFullYear(new Date().getFullYear())), tup[1] 
])

A quick test to make sure it works in both browsers.

1 Like

damn your browser differences! but thank you it works perfectly now :o) i almost never use anything other than firefox so i didnt think to check in a different browser