【问题标题】:Moment.js how to get week of month? (google calendar style)Moment.js 如何获得一个月的一周? (谷歌日历样式)
【发布时间】:2014-02-12 19:41:45
【问题描述】:

我正在使用 Moment.js,它很棒。我现在遇到的问题是我无法弄清楚如何获得某个日期的月份周数。我只能在 Moment js 文档中找到“一年中的一周”。例如,如果我选择今天的日期(2014 年 2 月 12 日),我想知道这个日期是 2 月的第二周,因此,它是该月的第二个星期三。有什么想法吗?

编辑: 我想一些澄清是必要的。我最需要的是一个月中某一天的第n个数字。例如,(来自 cmets)2014 年 2 月 1 日将是该月的第一个星期六。 2014 年 2 月 3 日将是该月的第一个星期一,即使它“技术上”是该月的第二周。基本上,谷歌日历的重复功能是如何对天进行分类的。

【问题讨论】:

  • 你想如何定义行为? 2014 年 2 月 1 日是星期六。 2 月 3 日是该月的第一周还是第二周?
  • 对于 2014 年 2 月 1 日,我认为是本月的第一个星期六。对于 2014 年 2 月 3 日,我认为是本月的第一个星期一。基本上,谷歌日历是如何分类的。

标签: javascript jquery momentjs


【解决方案1】:

moment.js 似乎没有实现您正在寻找的功能的方法。 但是,您可以使用date / 7Math.ceil 找到一个月中某一天的第n 个数字 例如:

var firstFeb2014 = moment("2014-02-01"); //saturday
var day = firstFeb2014.day(); //6 = saturday
var nthOfMoth = Math.ceil(firstFeb2014.date() / 7); //1

var eightFeb2014 = moment("2014-02-08"); //saturday, the next one
console.log( Math.ceil(eightFeb2014.date() / 7) ); //prints 2, as expected

这似乎是您要查找的号码,如以下测试所示

function test(mJsDate){
   var str = mJsDate.toLocaleString().substring(0, 3) +
             " number " + Math.ceil(mJsDate.date() / 7) +
             " of the month";
   return str;
}

for(var i = 1; i <= 31; i++) {
   var dayStr = "2014-01-"+ i;
   console.log(dayStr + " " + test(moment(dayStr)) );
}

//examples from the console:
//2014-01-8 Wed number 2 of the month
//2014-01-13 Mon number 2 of the month
//2014-01-20 Mon number 3 of the month
//2014-01-27 Mon number 4 of the month
//2014-01-29 Wed number 5 of the month

【讨论】:

  • x.date() 是什么?
  • date 方法返回月份中的哪一天。
  • @skube x 应该是任何 momentjs 对象,在这个例子中它应该是 firstFeb2014,我编辑了答案以消除这种混乱。
  • 不适用于 2018 年 7 月 30 日。2018 年 7 月跨越 6 周。上述解决方案在该日期返回 5。
  • @Shardul 查看日历,2018 年 7 月实际上是 5 周。我错过了什么吗?
【解决方案2】:

在根据给定日期计算月份中的星期几时,您必须考虑偏移量。并非所有月份都从一周的第一天开始。

如果你想考虑这个偏移量,如果你正在使用矩,你可以使用类似下面的东西。

function weekOfMonth (input = moment()) {
  const firstDayOfMonth = input.clone().startOf('month');
  const firstDayOfWeek = firstDayOfMonth.clone().startOf('week');

  const offset = firstDayOfMonth.diff(firstDayOfWeek, 'days');

  return Math.ceil((input.date() + offset) / 7);
}

【讨论】:

  • 虽然这不能解决 OPs 问题,但它解决了我的问题 - 我需要像查看日历一样找到一个月中的星期几,即星期一 -> 星期日,第一周' 可能包括上个月的天数,谢谢
【解决方案3】:

moment.js 的简单使用

函数week_of_month(日期){ 前缀 = [1,2,3,4,5]; 返回前缀[0 |时刻(日期)。日期()/ 7] }

【讨论】:

  • 为什么不使用date.getDate() 而不是moment(date).date(),所以2017-07-27 会返回错误的一周
【解决方案4】:

这个库添加了函数moment.weekMonth() https://github.com/c-trimm/moment-recur

【讨论】:

    【解决方案5】:

    我根据反馈做了一些修改。

    let weeks = moment().weeks() - moment().startOf('month').weeks() + 1;
    weeks = (weeks + 52) % 52;
    

    在经过下一年的日子里,周值将是负数,所以我不得不加上 52。

    【讨论】:

    • moment().add(0, 'month').startOf('month').weeks()moment().startOf('month').weeks() 有什么区别,两者返回不同的值有什么情况
    • 对于 2021-12-31,它返回 -47 作为周数
    【解决方案6】:

    类似的东西呢:

    weekOfCurrentMonth = (moment().week() - (moment().month()*4));
    

    这需要一年中的当前周,然后减去前几个月数的 4 倍。哪个应该给你当月的一周

    【讨论】:

    • 我已经考虑过类似的事情,但问题是并非每个月都有 4 周。例如,上个月,2014 年 1 月,“技术上”有 5 周。
    • @train 除非你只计算整周,在这种情况下它有 3 个!不幸的是,您必须根据每周“属于”特定月份的定义来选择一个定义,并且没有一种公认的正确方法可以做到这一点。
    【解决方案7】:

    我认为这个问题的答案会有所帮助,即使它没有按要求使用 moment.js:

    Get week of the month

    【讨论】:

      【解决方案8】:
      function countWeekdayOccurrencesInMonth(date) {
      
          var m = moment(date),
                  weekDay = m.day(),
                  yearDay = m.dayOfYear(),
                  count = 0;
      
          m.startOf('month');
          while (m.dayOfYear() <= yearDay) { 
              if (m.day() == weekDay) {
                  count++; 
              }
              m.add('days', 1); 
          }
      
          return count;
      }
      

      【讨论】:

      • 您的回答和乔瓦尼的工作都完全符合我的需要。谢谢!
      【解决方案9】:

      @Daniel Earwicker 的回答有问题。 我在我的应用程序中使用了他的函数,由于以下情况,while 循环是无限的:

      我试图弄清楚 12 月(2016 年)的哪一周是第 31 天。 12 月的第一天是今年的第 336 天。 12 月的最后一天是一年中的第 366 天。

      这里的问题:当它是第 366 天(12 月 31 日,一年中的最后一天)时,代码在这个日期上又增加了一天。但再加上一天,它将是 2017 年 1 月的第 1 天。因此循环从未结束。

       while (m.dayOfYear() <= yearDay) { 
      
          if (m.day() == weekDay) {
              count++; 
          }
          m.add('days', 1); 
      }
      

      我在代码中添加了以下几行,以便解决问题:

      function countWeekdayOccurrencesInMonth(date) {
      
        var m = moment(date),
              weekDay = m.day(),
              yearDay = m.dayOfYear(),
              year = m.year(),
              count = 0;
      
       m.startOf('month');
      
       while (m.dayOfYear() <= yearDay && m.year() == year) {
          if (m.day() == weekDay) {
              count++;
          }
          m.add('days', 1);
       }
      
       return count;
      }
      

      它验证它是否仍在验证日期的同一年

      【讨论】:

        【解决方案10】:

        这是Robin Malfait 使用轻量级库date-fns 实现的解决方案

        import {
            differenceInDays,
            startOfMonth,
            startOfWeek,
            getDate
        } from 'date-fns'
        
        const weekOfMonth = function (date) {
            const firstDayOfMonth = startOfMonth(date)
            const firstDayOfWeek = startOfWeek(firstDayOfMonth)
            const offset = differenceInDays(firstDayOfMonth, firstDayOfWeek)
            return Math.ceil((getDate(date) + offset) / 7)
        }
        
        export default weekOfMonth
        

        【讨论】:

          【解决方案11】:

          我会做以下事情:

          let todaysDate = moment(moment.now());
          let endOfLastMonth = moment(get(this, 'todaysDate')).startOf('month').subtract(1, 'week');
          
          let weekOfMonth = todaysDate.diff(endOfLastMonth, 'weeks');
          

          得到todaysDateendOfLastMonth,然后使用 Moment 的内置 diff() 方法计算当前月份的周数。

          【讨论】:

            【解决方案12】:

            它不是内置的,但基本上你可以从相关日期的周数中减去月初的周数。

            function weekOfMonth(m) {
              return m.week() - moment(m).startOf('month').week() + 1;
            }
            

            感谢原authorcode,如果对你有帮助,请给他一颗星。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-04-19
              • 2020-07-19
              • 1970-01-01
              • 2014-01-20
              相关资源
              最近更新 更多