Javascript 使用天/周和标题创建带有时刻的自定义日历

Javascript 使用天/周和标题创建带有时刻的自定义日历,javascript,html,datetime,calendar,momentjs,Javascript,Html,Datetime,Calendar,Momentjs,我正在使用moment and react创建一个时间表组件。我已经创建了一个自定义日历。如何将一周中的几天固定在顶部,就像普通日历一样?因此,如果我将date对象传递到Mapter,我希望在每个日期上方呈现所有日期,并在一周中的正确日期标题。我在这里创作了一把小提琴 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:

我正在使用moment and react创建一个时间表组件。我已经创建了一个自定义日历。如何将一周中的几天固定在顶部,就像普通日历一样?因此,如果我将date对象传递到Mapter,我希望在每个日期上方呈现所有日期,并在一周中的正确日期标题。我在这里创作了一把小提琴

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 GMT+0800(CST)''Mon Sep 05 2016 00:00:00 GMT+0800(CST)''星期二Sep 06 00:00 GMT+0800(CST)'Wed Sep 07 2016 00:00+0800(CST)'“2016年9月8日星期四00:00:00 GMT+0800(CST)”,“2016年9月9日星期五00:00 GMT+0800(CST)”,“2016年9月10日星期六00:00 GMT+0800(CST)”,“2016年9月11日星期日00:00:00 GMT+0800(CST)”,“2016年9月13日星期二00:00 GMT+0800(CST)”,“2016年9月14日星期三00:00 GMT+0800(CST)”,“2016年9月15日星期四00:00 GMT+0800(CST)”“2016年9月16日星期五00:00:00 GMT+0800(CST)”,“2016年9月17日星期六00:00 GMT+0800(CST)”,“2016年9月18日星期日00:00:00 GMT+0800(CST)”,“2016年9月19日星期一00:00 GMT+0800(CST)”,“2016年9月21日星期三00:00 GMT+0800(CST)”,“2016年9月22日星期四00:00 GMT+0800(CST)”,“2016年9月23日00:00 GMT”“2016年9月24日星期六00:00:00 GMT+0800(CST)”,“2016年9月25日太阳00:00 GMT+0800(CST)”,“2016年9月26日星期一00:00 GMT+0800(CST)”,“2016年9月27日星期二00:00 GMT+0800(CST)”,“2016年9月28日星期三00:00 GMT+0800(CST)”,“2016年9月29日星期四00:00 GMT+0800(CST)”,“2016年9月30日星期五00:00 GMT+0800(CST)”]
var Hello=React.createClass({
render:function(){
返回
{dates.map(函数(天){
返回(
{moment(day).format('D').toString()}
)
})}
;
}
});
ReactDOM.render(
,
document.getElementById('容器')
);
这就是我所拥有的

这就是我想要的,与日期编号对应的一周中的天数。周一、周二、周三。。。。。

使用表格作为标题获取,并使用矩转换周和天

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'))
  })
}
const startWeek=moment().startOf('month').week();
const endWeek=moment().endOf('month').week();
让日历=[]
对于(var week=startWeek;week moment().week(week).startOf('week').clone().add(n+i,'day'))
})
}

根据CaffineScript提供的答案,我创建了这个日历,它也可以围绕年份边界工作

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()};
            }
        )
    );
}

基于以上所有答案:

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())
    });
简化版

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')) }));
}

@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)
        }
    }
let testAll=(月、年)=>{
const monthYear=矩().年.月
const firstDay=monthYear.startOf(“月”);
const endDay=moment().年(年).月(月).endOf(“月”);
常量日历=工作日(月、年);
描述(“测试日历”,()=>{
它('检查第一个日期是否在第一周/应为真',()=>{
预期(日历[0][“天”].filter((天)=>day.date()==firstDay.date())[0]。格式(“YYYY-MM-DD”)==firstDay.format(“YYYY-MM-DD”)。toBe(true);
});
它('检查结束日期是否在周末/应为真',()=>{
预期(日历[calendar.length-1][“days”].filter((day)=>day.date()==endDay.date())[0]。格式(“YYYY-MM-DD”)==endDay.format(“YYYY-MM-DD”)。toBe(true);
});
});
}
对于(假设y=2000;y<2100;y++){

for(设m=0;m
moment('2017-12-31').endOf('month').week();
返回1,因为根据moment,它是(var week=startWeek;week显然,在返回日期之前添加了一天。这不会导致输出数组中的日期错误吗?此函数不包括最后一天,因为它与endDay相同。您可以像这样使用
isSameOrBefore
方法:
index.isSameOrBefore(endDay,'day'))
它是否与react兼容?这应该是新的接受答案。当前接受的答案与2019年12月的结果不符。无法读取未定义的属性“clone”?@Martian2049使用矩库
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)
        }
    }