根据 ISO 标准,我每月需要整数周。
而且我使用的是 momentJS 而不是 Js 的 Date。
根据 ISO 日期格式,如果该月有星期四,则计算该月的周数,否则计算上个月的周数。
据此,今年四舍五入周数为 5 的月份 ( 2018 ) 是:
火星、五月、八月和十一月
据说其余的有 4 周。
这是我的代码(灵感 here ):
编辑,如果我不应用评论中建议的修复,我最终会在 2018 年 12 月花费 1 周的时间,与 2017 年相同。
ngOnInit() {
this.generateTimelineForGivenYear('2018');
}
generateTimelineForGivenYear(year){
for (let i = 1; i < 13; i++) {
let month;
if (i < 10) month = '0'.concat(i.toString());
else month = i;
this.howManyWeeksForGivenMonth(moment(year + '-'+ month + '-05'));
}
}
howManyWeeksForGivenMonth(myDate){
console.log('The Month : ', myDate.month() + 1);
const start = myDate.clone().startOf('month').week();
let end = myDate.clone().endOf('month').week();
if( start > end ){ end = 52 + end }
const res = end - start;
console.log('The Number of Weeks: ', res);
console.log('----------------------------------------------------');
}
我的结果:
The Month : 1
The Number of Weeks: 4
----------------------------------------------------
The Month : 2
The Number of Weeks: 4
----------------------------------------------------
The Month : 3
The Number of Weeks: 4
----------------------------------------------------
The Month : 4
The Number of Weeks: 4
----------------------------------------------------
The Month : 5
The Number of Weeks: 4
----------------------------------------------------
The Month : 6
The Number of Weeks: 4
----------------------------------------------------
The Month : 7
The Number of Weeks: 4
----------------------------------------------------
The Month : 8
The Number of Weeks: 4
----------------------------------------------------
The Month : 9
The Number of Weeks: 5
----------------------------------------------------
The Month : 10
The Number of Weeks: 4
----------------------------------------------------
The Month : 11
The Number of Weeks: 4
----------------------------------------------------
The Month : 12
The Number of Weeks: 5
----------------------------------------------------
如你所见,我得到了两个月个月,即 5 周,但也不正确:
九月和十二月
我也尝试过:
howManyWeeksForGivenMonth(myDate){
console.log('The Month : ', myDate.month() + 1);
const first = myDate.day() == 0 ? 6 : myDate.day()-1;;
const day = 7-first;
const last = myDate.daysInMonth();
let res = Math.floor((last-day)/7);
if ((last-day) % 7 !== 0) res++;
console.log('The Number of Weeks: ', res);
console.log('----------------------------------------------------');
}
这给出了:
The Month : 1
The Number of Weeks: 4
----------------------------------------------------
The Month : 2
The Number of Weeks: 3
----------------------------------------------------
The Month : 3
The Number of Weeks: 4
----------------------------------------------------
The Month : 4
The Number of Weeks: 4
----------------------------------------------------
The Month : 5
The Number of Weeks: 5
----------------------------------------------------
The Month : 6
The Number of Weeks: 4
----------------------------------------------------
The Month : 7
The Number of Weeks: 4
----------------------------------------------------
The Month : 8
The Number of Weeks: 5
----------------------------------------------------
The Month : 9
The Number of Weeks: 4
----------------------------------------------------
The Month : 10
The Number of Weeks: 4
----------------------------------------------------
The Month : 11
The Number of Weeks: 4
----------------------------------------------------
The Month : 12
The Number of Weeks: 4
----------------------------------------------------
...没有更好。
我做错了什么?
更新:
一旦发现我周四没有剪辑是问题所在,这是我的新尝试:
howManyWeeksForGivenMonth(myDate){
console.log('The Month ', myDate.month() + 1 );
let weeks = 4
if(myDate.clone().startOf('month').weekday() >= 5 ){
weeks ++;
console.log('first week extra');
}
if(myDate.clone().endOf('month').weekday() < 5 ) {
weeks ++;
console.log('last week extra');
}
return weeks;
}
我明白了:
The Month 1
last week extra
5
The Month 2
last week extra
5
The Month 3
4
The Month 4
last week extra
5
The Month 5
last week extra
5
The Month 6
first week extra
5
The Month 7
last week extra
5
The Month 8
4
The Month 9
first week extra
last week extra
6
The Month 10
last week extra
5
The Month 11
4
The Month 12
first week extra
last week extra
6
这里没有什么可读的,只是纯粹的垃圾。
显然,我知道两个 if 永远不应该在一个月内同时触发,但我原以为这根本不会发生。
我认为是错的,但除此之外它仍然不对应于正确的月份。那么现在是什么情况呢?
最佳答案
我不遵循您确定当月周数的方法。我的方法是计算第一个星期四之后还剩下多少天:如果有28天或更多,则有5周。否则有 4 个。
/* @param {number} year - full year
** @param {number} month - calendar month number (Jan = 1, Feb = 2, etc.)
** @returns {number} weeks in month
*/
function weeksInMonth(year, month) {
// Create a Date for the given year and month
var d = new Date(year, month-1, 1);
// Get the number of days in the month
var daysInMonth = new Date(year, month, 0).getDate();
// Get date of first Thursday
var firstThuDate = (11 - d.getDay()) % 7 + 1;
// Get number of days in month after 1st Thursday
var daysLeft = daysInMonth - firstThuDate;
// If there are 28 or more days left, there are 5 weeks
// Otherwise, there are 4
return daysLeft > 27? 5 : 4;
}
// Weeks in 2018 months
for (var i=0; i<12; i++) {
var monthName = new Date(2018,i).toLocaleString(undefined, {month:'short'});
console.log(monthName + ' 2018: ' + weeksInMonth(2018,i+1));
}
当然,您可以将上面的代码减少到更少的代码,这是为了算法的清晰而编写的。
使用 moment.js 的相同算法:
// Count ISO weeks in month
function weeksInMonth(year, month) {
// Create moment object
var d = moment([year, month - 1, 1]);
// Get date of first Thursday
var firstThu = d.weekday(4).date();;
// Subtract from last day of month
var daysLeft = d.endOf('month').date() - firstThu;
// If days left > 27, there are 5 weeks
// Otherwise there are 4
return daysLeft > 27 ? 5 : 4;
}
// Weeks in 2018 months
for (var i=0; i<12; i++) {
var monthName = new Date(2018,i).toLocaleString(undefined, {month:'short'});
console.log(monthName + ' 2018: ' + weeksInMonth(2018,i+1));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script>
关于javascript - 采用 ISO 格式的每月周数(如果跨过星期四则算周数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50155397/