Reputation: 375
I looked around Stack and found a few other examples of calculating the season from a Date but I was not sure about performance if it was passed thousands of Date objects. The other Stack OP, someone advised that converting the Date to time and then comparing the integers was the most perfoamant so I wrote the following function to calculate the season of the date passed.
function season(d) {
day = new Date(d);
days = day.getTime();
const SPRING_START = new Date(day.getFullYear(), 2, (day.getFullYear() % 4 === 1) ? 19 : 20).getTime();
const SUMMER_START = new Date(day.getFullYear(), 5, (day.getFullYear() % 4 === 1) ? 20 : 21).getTime();
const AUTUMN_START = new Date(day.getFullYear(), 8, (day.getFullYear() % 4 === 1) ? 22 : 23).getTime();
const AUTUMN_END = new Date(day.getFullYear(), 11, (day.getFullYear() % 4 === 1) ? 20 : 21).getTime();
const s = [SPRING_START, SUMMER_START, AUTUMN_START, AUTUMN_END];
const S_NAME = ["Spring", "Summer", "Autumn", "Winter"];
for( i = 0; i < s.length - 1; i++ ) {
if(days >= s[i] && days < s[i + 1]) {
season = S_NAME[i];
break;
}
season = S_NAME[3];
}
return season;
}
document.write(season("8/1/2019"));
// "Summer"
It works, but I am looking for advice on how to make it more concise, perhaps with ES6 methods, or objects instead of arrays, as I am still on the learning curve for those concepts.
Upvotes: 1
Views: 3399
Reputation: 375
After a lot of trial and error, I was able to answer my own question using ES6 methods:
const d = new Date("3/19/2020");
var seasonArray = [
{name: 'Spring', date: new Date(d.getFullYear(),2,(d.getFullYear() % 4 === 0) ? 19 : 20).getTime()},
{name: 'Summer', date: new Date(d.getFullYear(),5,(d.getFullYear() % 4 === 0) ? 20 : 21).getTime()},
{name: 'Autumn', date: new Date(d.getFullYear(),8,(d.getFullYear() % 4 === 0) ? 22 : 23).getTime()},
{name: 'Winter', date: new Date(d.getFullYear(),11,(d.getFullYear() % 4 === 0) ? 20 : 21).getTime()}
];
const season = seasonArray.filter(({ date }) => date <= d).slice(-1)[0] || {name: "Winter"}
console.log(new Date(d).toLocaleDateString(), season.name);
// "1/1/2019" "Winter"
// "3/19/2019" "Winter"
// "3/19/2020" "Spring"
// "11/25/2022" "Autumn"
// "12/31/2023" "Winter"
The object array is populated with the target date Equinox and Solstice days for the northern hemisphere. You will have to adjust the array accordingly for the southern hemisphere.The filter command returns object dates that are less that the target date, then the last value of the array is sliced, and finally if undefined, a static value. I hope this helps for future searches.
Upvotes: 10