最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

arrays - Javascript Calculate Season - Stack Overflow

programmeradmin9浏览0评论

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 paring 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.

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 paring 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.

Share Improve this question asked Aug 1, 2019 at 18:19 rewrew 3853 silver badges17 bronze badges 4
  • 1 Please note that even the assumption that there are four seasons starting at the dates you've chosen is entirely false for many parts of the world. Might not be an issue, but working with dates is always super tricky, which is why we almost always rely on heavily tested and vetted libraries. Of course, I doubt that moment.js has "season" support. – Mike 'Pomax' Kamermans Commented Aug 1, 2019 at 18:23
  • 3 Questions about optimizing or refactoring working code are better suited on codereview.stackexchange. Make sure to read their terms first – charlietfl Commented Aug 1, 2019 at 18:24
  • 2 So, you're looking for a Code Review? ;) – Karl-André Gagnon Commented Aug 1, 2019 at 18:24
  • 2 On a secondary note: don't use document.write, ever. It's an extremely low level legacy function that does not do what you think it does at all. Use console.log if you just want to see what a value ended up being, – Mike 'Pomax' Kamermans Commented Aug 1, 2019 at 18:25
Add a ment  | 

1 Answer 1

Reset to default 10

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 mand 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.

发布评论

评论列表(0)

  1. 暂无评论