【问题标题】:creating a custom calendar with moment using days/weeks and headings使用天/周和标题创建带有时刻的自定义日历
【发布时间】:2016-09-30 07:51:55
【问题描述】:

我正在使用时刻和反应创建计划组件。我创建了一个自定义日历。如何像普通日历一样将星期几固定在顶部?因此,如果我通过日期对象 september,我想在每个日期上方显示正确的星期几标题的所有日期。我在这里创建了一个小提琴。

https://jsfiddle.net/4dbwLg6b/

var dates = ['Thu Sep 01 2016 00:00:00 GMT+0800 (CST)', 'Fri Sep 02 2016 00:00:00 GMT+0800 (CST)', 'Sat Sep 03 2016 00:00:00 GMT+0800 (CST)', 'Sun Sep 04 2016 00:00:00 GMT+0800 (CST)', 'Mon Sep 05 2016 00:00:00 GMT+0800 (CST)', 'Tue Sep 06 2016 00:00:00 GMT+0800 (CST)', 'Wed Sep 07 2016 00:00:00 GMT+0800 (CST)', 'Thu Sep 08 2016 00:00:00 GMT+0800 (CST)', 'Fri Sep 09 2016 00:00:00 GMT+0800 (CST)', 'Sat Sep 10 2016 00:00:00 GMT+0800 (CST)', 'Sun Sep 11 2016 00:00:00 GMT+0800 (CST)', 'Mon Sep 12 2016 00:00:00 GMT+0800 (CST)', 'Tue Sep 13 2016 00:00:00 GMT+0800 (CST)',' Wed Sep 14 2016 00:00:00 GMT+0800 (CST)',' Thu Sep 15 2016 00:00:00 GMT+0800 (CST)', 'Fri Sep 16 2016 00:00:00 GMT+0800 (CST)', 'Sat Sep 17 2016 00:00:00 GMT+0800 (CST)', 'Sun Sep 18 2016 00:00:00 GMT+0800 (CST)', 'Mon Sep 19 2016 00:00:00 GMT+0800 (CST)',' Tue Sep 20 2016 00:00:00 GMT+0800 (CST)', 'Wed Sep 21 2016 00:00:00 GMT+0800 (CST)', 'Thu Sep 22 2016 00:00:00 GMT+0800 (CST)', 'Fri Sep 23 2016 00:00:00 GMT+0800 (CST)', 'Sat Sep 24 2016 00:00:00 GMT+0800 (CST)', 'Sun Sep 25 2016 00:00:00 GMT+0800 (CST)', 'Mon Sep 26 2016 00:00:00 GMT+0800 (CST)', 'Tue Sep 27 2016 00:00:00 GMT+0800 (CST)', 'Wed Sep 28 2016 00:00:00 GMT+0800 (CST)', 'Thu Sep 29 2016 00:00:00 GMT+0800 (CST)', 'Fri Sep 30 2016 00:00:00 GMT+0800 (CST)']
var Hello = React.createClass({
  render: function() {


    return <div className="container">
       {dates.map(function(day){
     return(
     <div className="calendarDay">
     {moment(day).format('D').toString()}
     </div>
     )
     })}
    </div>;
  }
});

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

这就是我所拥有的

这就是我想要的,对应于日期编号的星期几。周一,周二,周三......

【问题讨论】:

    标签: javascript html datetime calendar momentjs


    【解决方案1】:

    根据以上所有答案:

    const calendar = [];
    const today = moment();
    const startDay = today.clone().startOf('month').startOf('week');
    const endDay = today.clone().endOf('month').endOf('week');
    
    let date = startDay.clone().subtract(1, 'day');
    
    while (date.isBefore(endDay, 'day')) 
        calendar.push({
            days: Array(7).fill(0).map(() => date.add(1, 'day').clone())
        });
    

    【讨论】:

    • 与react兼容吗?
    • 这应该是新接受的答案。当前接受的答案在 2019 年 12 月表现不佳。
    • 无法读取未定义的属性“克隆”?
    • @Martian2049 使用矩库
    • 请注意,如果您的一周从星期一开始,您必须使用isoWeek 来表示.startOf.endOf
    【解决方案2】:

    使用表格作为标题,并使用 moment 转换周数和天数

    const startWeek = moment().startOf('month').week();
    const endWeek = moment().endOf('month').week();
    
    
    let calendar = []
    for(var week = startWeek; week<endWeek;week++){
      calendar.push({
        week:week,
        days:Array(7).fill(0).map((n, i) => moment().week(week).startOf('week').clone().add(n + i, 'day'))
      })
    }
    

    【讨论】:

    • moment('2017-12-31').endOf('month').week(); return 1
    • 那是因为根据时刻,它是stackoverflow.com/questions/25631682/…
    • for (var week = startWeek; week &lt;= endWeek; week++)
    • 您的解决方案非常有用。谢谢。调整到完美日期的几处修正...... for(var week = startWeek; week&lt;=endWeek;week++){ 和...... moment().week(week).startOf('week').clone().add(i + 1, 'day'))
    • 我后来意识到你不需要添加一个。当您将每个日期转换为实际日期时,它将是正确的。 2022-01-29T23:00:00.000Z 在我用时刻提取日期时给了我 30。试试这个.....moment("2022-01-29T23:00:00.000Z").format(),你会得到 2022-01-30T00:00:00+01:00
    【解决方案3】:

    根据 caffeinescript 提供的答案,我创建了这个日历,它也可以在年份范围内工作。

    const startDay = moment().clone().startOf('month').startOf('week');
    const endDay = moment().clone().endOf('month').endOf('week');
    
    var calendar = [];
    var index = startDay.clone();
    while (index.isBefore(endDay, 'day')) {
        calendar.push(
            new Array(7).fill(0).map(
                function(n, i) {
                    return {date: index.add(1, 'day').date()};
                }
            )
        );
    }
    

    【讨论】:

    • 显然,在返回日期之前添加了一天。这不会导致输出数组中的日期错误吗?
    • 此函数不包括最后一天,因为它与 endDay 相同。您可以像这样使用isSameOrBefore 方法:index.isSameOrBefore(endDay, 'day')
    【解决方案4】:

    简化版

    function weekDays(month, year) {
      const endDate = moment().date(0).month(month).year(year);
    
      return Array(endDate.date()).fill(0).map((_, i) => moment().date(i + 1).month(month).year(year))
        .map((day) => ({ day, week: day.week() }))
        .filter(({ week }, i, arr) => arr.findIndex((info) => info.week === week) === i)
        .map(({ day, week }) => ({ week, days: Array(7).fill(0).map((_, i) => moment(day).week(week).startOf('week').add(i, 'day')) }));
    }
    

    【讨论】:

      【解决方案5】:

      @d0whc3r 的回答似乎是最准确的。我做了一些修改

      从 2000 年到 2100 年,我已经运行了 100 个日历年的单元测试

      亲爱的读者,如果你是 2100 年,请运行单元测试直到 2200 年。

      index.js

      function weekDays(month, year) {
          const endDate = moment.utc().year(year).month(month).endOf('month');
      
          return Array(endDate.date()).fill(0).map((_, i) => moment.utc().year(year).month(month).date(i + 1))
              .map((day) => ({day, week: day.week()}))
              .filter(({week}, i, arr) => arr.findIndex((info) => info.week === week) === i)
              .map(({day, week}) => ({
                  week,
                  days: Array(7).fill(0).map((_, i) => moment.utc(day).week(week).startOf('week').add(i, 'day'))
              }));
      
      }
      

      index.test.js

      let testAll = (month, year) => {
              const monthYear = moment().year(year).month(month)
              const firstDay = monthYear.startOf('month');
              const endDay = moment().year(year).month(month).endOf("month");
              const calendar = weekDays(month, year);
      
              describe("testing calendar", () => {
                  it('check if first date is in first week / should be true', () => {
                      expect(calendar[0]["days"].filter((day) => day.date() === firstDay.date())[0].format("YYYY-MM-DD") === firstDay.format("YYYY-MM-DD")).toBe(true);
                  });
      
                 it('check if end date is in end week / should be true', () => {
                      expect(calendar[calendar.length - 1]["days"].filter((day) => day.date() === endDay.date())[0].format("YYYY-MM-DD") === endDay.format("YYYY-MM-DD")).toBe(true);
                  });
              });
      
          }
          for (let y=2000; y < 2100; y++){
              for (let m = 0; m <= 11; m++) {
                  testAll(m, y)
                  console.log(m)
              }
          }
      

      P.S:我不是 javascript 专家,这是我的第一个单元测试

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-08
        • 1970-01-01
        • 2015-02-11
        • 1970-01-01
        • 2019-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多