C#开发甘特图时按指定刻度数生成均匀间隔日期序列的问题
甘特图自定义时间刻度计算逻辑及实现
核心计算逻辑
- 第一步:确认总刻度数
按照你给出的需求示例,用户输入自定义刻度数为n时,最终生成包含首尾起止日期的总刻度数为n + 2,可以完全匹配你的场景:- 输入n=10,总刻度数=10+2=12
- 若要实现输出起止+中间日期共3个刻度的效果,只需把总刻度数设为3即可,可根据你实际的参数定义灵活调整规则
- 第二步:计算总时间跨度
用结束日期减去开始日期,取时间的总Ticks值计算(比按天计算精度更高,能避免时区、夏令时、闰年导致的误差) - 第三步:计算单步间隔
间隔步长 = 总时间跨度 / (总刻度数 - 1),m个刻度之间共有m-1个均匀间隔 - 第四步:循环生成刻度数组
从开始日期起,依次加上i倍的步长(i从0到总刻度数-1),得到所有均匀分布的刻度日期,最后强制对齐结束日期避免整数除法误差
优化后的实现代码
/// <summary> /// 生成均匀分布的甘特图时间刻度数组 /// </summary> /// <param name="start">甘特图最早开始日期</param> /// <param name="end">甘特图最晚结束日期</param> /// <param name="userInputScale">用户输入的自定义内部刻度数</param> /// <returns>包含起止日期的均匀刻度数组</returns> public DateTime[] GenerateScaleDates(DateTime start, DateTime end, int userInputScale) { // 总刻度数 = 用户输入的内部刻度数 + 首尾2个刻度,若需求是用户输入总刻度数直接赋值即可 int totalScaleCount = userInputScale + 2; // 边界情况处理:总刻度数小于等于2时直接返回首尾日期 if (totalScaleCount <= 2) { return new DateTime[] { start.Date, end.Date }; } // 计算总时间跨度 long totalTicks = end.Ticks - start.Ticks; // 计算单步间隔的Ticks数 long stepTicks = totalTicks / (totalScaleCount - 1); // 生成刻度数组 DateTime[] scaleDates = new DateTime[totalScaleCount]; for (int i = 0; i < totalScaleCount; i++) { scaleDates[i] = new DateTime(start.Ticks + i * stepTicks).Date; } // 强制最后一个刻度等于结束日期,避免整数除法导致的微小误差 scaleDates[totalScaleCount - 1] = end.Date; return scaleDates; }
效果验证
以你的实际场景为例:总跨度160天,起止日期为2021-01-01到2021-06-10
- 生成3个刻度时:步长=160/2=80天,输出为
2021-01-01、2021-03-22、2021-06-10 - 生成12个刻度时:步长≈14.54天,依次累加后得到12个均匀分布的日期,首尾与起止日期完全一致
内容的提问来源于stack exchange,提问作者user17316418
相关产品推荐
相关产品推荐

