DHTMLX甘特图:无需修改起止日期实现工期含起始日计算咨询
问题描述
使用DHTMLX甘特图时,默认工期计算将起始日算作0天(例如2022/01/13到2022/01/15默认算2天),但我们需要把起始日算作1天(即上述日期区间算3天)。此前尝试过修改显示逻辑,但会导致与MS Project/PM6 XML导入导出时数据冲突,且不愿修改网格时间槽,希望找到无需修改起止日期即可实现该计算规则的方案。
当前代码配置:
var dateEditor = gantt.config.editor_types.date; gantt.config.duration_unit = "day"; gantt.config.work_time = true; gantt.setWorkTime({day : 1, hours: true}); gantt.setWorkTime({day : 2, hours: true}); gantt.setWorkTime({day : 3, hours: true}); gantt.setWorkTime({day : 4, hours: true}); gantt.setWorkTime({day : 5, hours: true}); gantt.setWorkTime({day : 6, hours: true}); gantt.setWorkTime({day : 7, hours: true}); gantt.config.columns = [ {name: "text", label: "Name", tree: true, width: 200, editor: textEditor, resize: true}, {name: "duration", label: "Duration", width:80, align: "center", editor: durationEditor, resize: true}, {name: "start_date", label: "Start", width:140, align: "center", editor: startDateEditor, resize: true}, {name: "end_date", label: "Finish", width:140, align: "center", editor: endDateEditor, resize: true} ]; gantt.calculateEndDate({start_date: new Date("2022/01/13"), duration:5}); console.log(gantt.calculateDuration({start_date: new Date("2022/01/13"), end_date: new Date("2022/01/15")})); gantt.init("gantt_here")
解决方案
直接重写DHTMLX甘特图的核心日期计算方法,修改工期与起止日期的转换逻辑,确保底层计算规则统一,避免导入导出冲突:
- 重写
calculateDuration方法:计算起止日期差后加1天(将起始日计入工期) - 重写
calculateEndDate方法:根据起始日期和工期,计算结束日期时减去1天(因为DHTMLX的结束日期为排他性日期,即任务到结束日期前一天完成)
具体代码修改如下:
// 保存原始方法引用 const originalCalculateDuration = gantt.calculateDuration; const originalCalculateEndDate = gantt.calculateEndDate; // 重写calculateDuration:起止日期差 +1天 gantt.calculateDuration = function(params) { const originalDuration = originalCalculateDuration.call(this, params); // 仅当起止日期都存在时调整,避免异常情况 if (params.start_date && params.end_date) { return originalDuration + 1; } return originalDuration; }; // 重写calculateEndDate:起始日期 + (duration-1)天 gantt.calculateEndDate = function(params) { if (params.start_date && typeof params.duration === "number") { // 创建新参数,将duration减1后调用原始方法 const adjustedParams = { start_date: params.start_date, duration: params.duration - 1, parent: params.parent, task: params.task }; return originalCalculateEndDate.call(this, adjustedParams); } return originalCalculateEndDate.call(this, params); };
说明
- 该方案直接修改核心计算逻辑,而非显示层,因此导入导出MS Project/PM6 XML时,API传输的数据计算规则统一,不会出现冲突
- 无需修改起止日期的存储或显示,网格时间槽保持原样
- 兼容工作时间配置(你当前设置所有天都为工作日,逻辑依然适用;若后续调整工作日规则,计算会自动适配)
内容的提问来源于stack exchange,提问作者Marwan Kheimi
相关产品推荐
相关产品推荐

