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