简体   繁体   English

如何在javascript中获得给定年份第一周的第一天?

[英]How do I get the first day of the first week in a given year, in javascript?

I think these are the correct conditions:认为这些是正确的条件:

  • Week 1 is the first week with at least 4 days of the new year.第 1 周是新年至少有 4 天的第一周。
  • Week 53 happens when the new years' first day is a Thursday OR it's a leapyear and the year' first day is a Wednesday.第 53 周发生在新年的第一天是星期四或闰年并且一年的第一天是星期三时。

Examples:例子:

Year (Input)年份(输入) First day of first week (return wanted)第一周的第一天(需要退货)
2020 (Leap Year) 2020(闰年) 30/12/2020 2020 年 12 月 30 日
2021 2021 04/01/2021 2021 年 4 月 1 日
2022 2022 03/01/2022 2022 年 3 月 1 日
2023 2023 02/01/2023 2023 年 2 月 1 日
2024 (Leap Year) 2024(闰年) 01/01/2024 2024 年 1 月 1 日
2025 2025 30/12/2025 2025 年 12 月 30 日
2026 (Starts on a wednesday, in a year of 53 weeks) 2026(从星期三开始,一年 53 周) 29/12/2026 29/12/2026

The year 2026 is a rare case, which happens in year 2032, 2037, 2043... 2026年是罕见的情况,发生在2032年、2037年、2043年……

I believe I've 'solved' half the problem here:我相信我在这里“解决”了一半的问题:

let numOfWeeks = 52;

if (((0 == year % 4 && 0 != year % 100) || 0 == year % 400) && 'first day of first week is a wednesday') {
    numOfWeeks = 53;
} else if ('first day of first week is a thursday') {
    numOfWeeks = 53
}

But I can't for the life of me figure out how to get the first day of the first week in a given year.但是我一生都无法弄清楚如何获得给定年份第一周的第一天。

so I have two solutions to offer 1 quite simple (making use of the Date object - basically doing what barrycarter suggested in a comment)所以我有两种解决方案来提供 1 非常简单(利用 Date 对象 - 基本上按照 barrycarter 在评论中建议的方式)

Creating a Date object for the first of our desired year ... and then based on which day of the week that is, adjusting the date to end up with the first monday of the first week of the year为我们期望的第一年创建一个 Date 对象......然后根据一周中的哪一天,将日期调整为一年中第一周的第一个星期一

As you might notice when running the code.正如您在运行代码时可能会注意到的那样。 The answers are off by (mostly 1 hour) - I don't know why, and so far I only encountered this when running my code on here - in VS Code and several Online JS Playgrounds the code returned exactly what I intended it to return.答案在(主要是 1 小时)之前关闭 - 我不知道为什么,到目前为止我只在这里运行我的代码时遇到过这个问题 - 在 VS Code 和几个在线 JS Playgrounds 中,代码返回的正是我想要返回的内容. So yeah there's that.所以是的,就是这样。

(date.getDay() + 6) % 7 // 0 - 6 for Mon - Sun

 function getDateOfFirstDayOfFirstWeek(year) { const date = new Date(year, 0, 1) if ((date.getDay() + 6) % 7 === 0) return date if ((date.getDay() + 6) % 7 < 4) { date.setDate(date.getDate() - (date.getDay() + 6) % 7) return date } else { date.setDate(8 - (date.getDay() + 6) % 7) return date } } console.log(getDateOfFirstDayOfFirstWeek(2020)) console.log(getDateOfFirstDayOfFirstWeek(2021)) console.log(getDateOfFirstDayOfFirstWeek(2022)) console.log(getDateOfFirstDayOfFirstWeek(2100)) console.log(getDateOfFirstDayOfFirstWeek(3567)) console.log(getDateOfFirstDayOfFirstWeek(2002)) console.log(getDateOfFirstDayOfFirstWeek(1845))

the 2nd option is a tad more complicated (and I mostly wrote it just for fun - but I'll share it nonetheless maybe there's something you can take away from it)第二个选项有点复杂(我写它主要是为了好玩——但我还是会分享它,也许你可以从中拿走一些东西)

Since I did not once use the Date object the missing hour problem does not happen here.由于我没有使用过 Date 对象,因此这里不会发生缺少时间的问题。 (I want to say again I've only encountered the missing hour on stackoverflow so far - so you should be fine using the above function) (我想再说一遍,到目前为止,我只遇到过 stackoverflow 上缺少的一小时 - 所以你应该可以使用上面的函数)

When we look at neighboring years we can see, that the date changes by 1 per year (and 2 if the year is a leap year) - so what we do is ... starting at an arbitrary point (I have chosen the year 2020 with the 30th of Dec being the Monday) we calculate the next/previous year (by adding/subtracting 1 or 2 from our date) ... we do that so long until we reach our desired year ...当我们查看相邻年份时,我们可以看到,日期每年变化 1(如果年份是闰年,则变化 2) - 所以我们所做的是......从任意点开始(我选择了 2020 年12 月 30 日是星期一)我们计算下一年/上一年(通过从我们的日期添加/减去 1 或 2)......我们这样做很长时间,直到我们达到我们想要的年份......

until the very end (where we convert everything into day/month/year) we store our date in a value x (which can become any integer)直到最后(我们将所有内容转换为日/月/年),我们将日期存储在值 x 中(可以成为任何整数)

x % 7 = 0 -> 29/12
x % 7 = 1 -> 30/12
x % 7 = 2 -> 31/12
x % 7 = 3 -> 01/01
x % 7 = 4 -> 02/01
x % 7 = 5 -> 03/01
x % 7 = 6 -> 04/01

This thing here is to add a proper modulo method ... because % in Javascript only returns the remainder not modulo (which matters when using negative values) see this answer for more information on that: https://stackoverflow.com/a/4467559/19529102 (that's also where I got this little bit of code from)这件事是添加一个适当的模数方法......因为 % 在Javascript中只返回余数而不是模数(这在使用负值时很重要)请参阅此答案以获取更多信息: https ://stackoverflow.com/a/ 4467559/19529102 (这也是我从中获得这一点代码的地方)

Number.prototype.mod = function (n) {
"use strict";
return ((this % n) + n) % n;};

 Number.prototype.mod = function (n) { "use strict"; return ((this % n) + n) % n; }; function isLeapYear(year) { if (year % 4 !== 0) return false; if (year % 100 !== 0) return true; if (year % 400 !== 0) return false; return true } function getFirstDayForNplus1(year, value) { if (isLeapYear(year)) return [year + 1, value - 2] return [year + 1, value - 1] } function getFirstDayForNminus1(year, value) { if (isLeapYear(year - 1)) return [year - 1, value + 2] return [year - 1, value + 1] } function getDateOfFirstDayOfFirstWeek(year) { if (year < 1583) return let baseLine = [2020, 1] if (year > baseLine[0]) { while (baseLine[0] !== year) { baseLine = getFirstDayForNplus1(...baseLine); } } else { while (baseLine[0] !== year) { baseLine = getFirstDayForNminus1(...baseLine); } } const month = baseLine[1].mod(7) < 2 ? 12 : 1; const day = (baseLine[1].mod(7) + 29) % 31 || 1 const retYear = month === 12 ? baseLine[0] - 1 : baseLine[0] return day + "/" + month + "/" + retYear } console.log(getDateOfFirstDayOfFirstWeek(2020)) console.log(getDateOfFirstDayOfFirstWeek(2021)) console.log(getDateOfFirstDayOfFirstWeek(2022)) console.log(getDateOfFirstDayOfFirstWeek(2100)) console.log(getDateOfFirstDayOfFirstWeek(3567)) console.log(getDateOfFirstDayOfFirstWeek(2002)) console.log(getDateOfFirstDayOfFirstWeek(1845))

since you have a year, month, day variable in the function, you could easily create a Date object using that function (if needed)由于函数中有年、月、日变量,因此可以使用该函数轻松创建 Date 对象(如果需要)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM