首页 文章

Moment.js:按给定年份获得第一周的第一天

提问于
浏览
1

我试图在给定的一天获得第一周的第一天

Correct results :

2017 = 2016年1月2日(星期一)= 2015年1月4日(星期一)= 2014年1月1日(星期四)= 1月1日(星期三)= 1月1日(星期二)

我可以通过以下方式获得 the first day of the year

moment().year(year).startOf('year') // All result is 1. jan XXXX

Then I tried : (正确)

moment().day(1).year(2017).week(1) // 2 Jan (Monday) (correct)

But when changed to 2016 : (错)

moment().day(1).year(2016).week(1) // 10 Jan (Sunday) (wrong)

有谁知道如何得到正确的结果? (我也开放纯JS date()

PS: Week number 的基础是 Norway

Playground : https://jsfiddle.net/6sar7eb4/

3 回答

  • 2

    没有必要使用循环,您可以使用week()来测试周数是否为 1

    时刻#周的输出将取决于当时的区域设置 .

    您必须使用locale()方法将语言环境设置为片刻,以便知道星期语言环境的开始 . 如果你必须用英语显示结果,你可以change locale locally .

    这是一个工作样本:

    function getFirstDayOfFirstWeekByYear( year ) {
      // Create moment object for the first day of the given year
      let func = moment({year:year})
      // Check if 1st of January is in the first week of the year
      if( func.week() !== 1 ){
        // If not, add a week to the first day of the current week
        func.startOf('week').add(1, 'week');
      }
      // Return result using english locale
      return func.locale('en').format('D. MMMM YYYY (dddd)')
    }
    
    // Set Norwegian Bokmål locale globally
    moment.locale('nb');
    
    // Tester
    [2017, 2016, 2015, 2014, 2013].forEach(function ( year ) {
      let s = '<li>' + getFirstDayOfFirstWeekByYear( year ) + '</li>'
      document.getElementsByTagName('BODY')[0].innerHTML += s
    })
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment-with-locales.min.js"></script>
    
  • 2

    无论如何,如果你乐意在一个循环中这样做,这是有效的

    function getFirstDayOfFirstWeekByYear( year ){
      let D = 1;
      x = 0;
      while(x !== 1){
       x = moment(`${year}-01-${D}`).isoWeek();
       if(x === 1 ){
        return moment(`${year}-01-${D}`).format('D. MMMM YYYY (dddd)')
       }
       D++;
      };
    }
    

    结果

    2. January 2017 (Monday)
    4. January 2016 (Monday)
    1. January 2015 (Thursday)
    1. January 2014 (Wednesday)
    1. January 2013 (Tuesday)
    
  • 4

    我试图在给定的一天获得第一周的第一天

    使用moment.js根据ISO 8601计划获得一年中第一周的第一天,您可以使用自周一ISO周开始以来一年中第一周的第一天:

    // Return a moment.js object for the first weekday of the first week
    // of the year using ISO 8601 scheme
    function firstDay(year) {
      return moment(year + '011', 'GGGGWWE');
    }
    
    // Examples
    ['2015', '2016', '2017', '2018', '2019', '2020']
    .forEach(function(year) {
      console.log('ISO First day of ' + year + ': ' +
                   firstDay(year).format('dddd D MMMM, YYYY'));
    });
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
    

    但是你似乎不想使用ISO方案,所以如果你只想获得一个不是星期六或星期日的一年中的第一天(即忽略ISO 8601方案),你可以做(没有moment.js) ):

    // Return Date for first day of year that is one of
    // Monday to Friday
    function firstDay(year) {
      var d = new Date(year, 0, 1);
      var day = d.getDay();
      d.setDate(d.getDate() + (day%6? 0 :  (++day%4)));
      return d;
    }
    
    // Examples
    ['2015', '2016', '2017', '2018', '2019', '2020']
    .forEach(function(year) {
      console.log('First weekday of ' + year + ': ' + firstDay(year).toString());
    });
    

    讨论

    一周的第一天和一年的第一天有许多不同的方案 . 一个常用的方案是ISO 8601,其中一周的第一天是星期一,一年的第一周是第一个星期四出现的那个(或者第一个星期四至少包含4天,它是相同的结果) .

    根据ISO 8601规则,2019年第一周的第一天是2018年12月31日星期一 .

    如果您决定支持不同的计划(例如在沙特阿拉伯,本周开始于周六,周五结束,周六至周三工作日,美国一周通常是周日至周六,周一至周五工作日),那么你应该明确说明您支持哪种方案,而不是简单地假设基于用户选择的语言的方案 . 计划也可能基于宗教等其他文化因素,因此不一定是基于地区或基于语言的 .

    沙特阿拉伯的英国人应该使用哪种方案?不丹的伊斯兰人?在沙特,商业官方语言是法语,但大多数国际讨论都是英语,而国家语言是阿拉伯语 . 但他们使用的是Hijri calendar,它与其他地方常用的格鲁吉亚历法不一致,并不是由语言定义,而是由宗教定义 .

    即使在同一个地方也可能存在差异,同一政府的部门选择不同的方案,因此即使区域设置(在术语的正确含义中)也不是使用哪种方案的明确指标 .

    如果您决定支持不同的方案,那么采用标准方案(如ISO 8601)要好得多,如果他们愿意,让用户将其更改为他们喜欢的方案(以及我的计算机和日历应用程序中的 preferences 允许我这样做) .

相关问题