Qt C++:将QDateTime时间段均匀拆分至10个无重复分组的问题求助
Qt C++:将日期区间均匀拆分为10个无重复分组
需求说明
- 给定起始
QDateTime和结束QDateTime,需将两者之间的所有日期(包含起止日期)均匀拆分为10个分组 - 分组要求无重复日期,逻辑规整:若总天数能被10整除,每组天数相同;若有余数,前N组各多1天,末尾组处理剩余天数(或总天数少于10时,前若干组各含1天,剩余组为空)
- 结果存储为
QMap<int, QList<QDate>>,键为1-10的分组编号,值为每组的起止日期列表
示例效果
起始日期:
QDateTime(QDate(2023,6,10), QTime(0,0,0))
结束日期:QDateTime(QDate(2023,6,30), QTime(0,0,0))
拆分结果:QMap((1, QList(QDate("2023-06-10"), QDate("2023-06-11"))) (2, QList(QDate("2023-06-12"), QDate("2023-06-13"))) (3, QList(QDate("2023-06-14"), QDate("2023-06-15"))) (4, QList(QDate("2023-06-16"), QDate("2023-06-17"))) (5, QList(QDate("2023-06-18"), QDate("2023-06-19"))) (6, QList(QDate("2023-06-20"), QDate("2023-06-21"))) (7, QList(QDate("2023-06-22"), QDate("2023-06-23"))) (8, QList(QDate("2023-06-24"), QDate("2023-06-25"))) (9, QList(QDate("2023-06-26"), QDate("2023-06-27"))) (10, QList(QDate("2023-06-28"), QDate("2023-06-30"))))
现有问题
- 原有算法总天数计算错误,导致分组边界重复
- 日期跳转逻辑不当,出现无效日期
- 未正确处理总天数少于10的场景
原有代码
#include <QMap> #include <QList> #include <QDateTime> #include <QDebug> QMap<int, QList<QDate>> splitDateTimeSlots(const QDateTime& startDateTime, const QDateTime& endDateTime, const QList<QDateTime>& parsedDateTimeList) { QMap<int, QList<QDate>> dateTimeInSlots; qint64 totalDays = startDateTime.date().daysTo(endDateTime.date()); qDebug() << "Total days ->" << totalDays << "Each slot should contain" << totalDays/10.0; int slotsNum = 10; // Calculate the number of days per slot qint64 daysPerSlot = totalDays / slotsNum; qint64 remainder = totalDays % slotsNum; // Initialize variables for holding the start and end dates of each slot QDateTime slotStart = startDateTime; QDateTime slotEnd; for(int i = 0; i < slotsNum; ++i) { slotEnd = slotStart.addDays(daysPerSlot).addSecs(-1); // Subtract one second to make it end of the day qint64 daysInSlot = daysPerSlot; if(remainder > 0) { daysInSlot += 1; remainder--; } QDateTime slotEndAdjusted = slotEnd.addDays(1); // Move one day ahead to make it start of next day // Adjust slot end date if it goes beyond the specified endDateTime if (slotEndAdjusted > endDateTime) { slotEndAdjusted = endDateTime; } QList<QDate> slotDates; slotDates << slotStart.date() << slotEndAdjusted.date(); // Add the start and end date of the slot to the map dateTimeInSlots[i+1] = slotDates; // Move the start date of the next slot to one day after the end date of the current slot slotStart = slotEndAdjusted.addDays(1); } return dateTimeInSlots; } int main() { QDateTime startDateTime(QDate(2023,6,10), QTime(0,0,0)); //selected start date and time QDateTime endDateTime(QDate(2023, 6, 23), QTime(0,0,0));//selected end date and time QList<QDateTime> parsedDateTimeList; parsedDateTimeList << QDateTime(QDate(2023,2,9), QTime(15,1,19)) << QDateTime(QDate(2023,4,3), QTime(14,59,8)) << QDateTime(QDate(2023,6,11), QTime(15,2,59)) << QDateTime(QDate(2023,6,29), QTime(15,1,16)) << QDateTime(QDate(2023,7,14), QTime(15,7,42)); QMap<int, QList<QDate>> dateTimeInSlots = splitDateTimeSlots(startDateTime, endDateTime, parsedDateTimeList); // Output the result for (auto it = dateTimeInSlots.begin(); it != dateTimeInSlots.end(); ++it) { qDebug() << "Slot" << it.key() << ":"; for (const auto& date : it.value()) { qDebug() << date.toString("yyyy-MM-dd"); } qDebug() << "---------------------"; } return 0; }
修正后的代码
#include <QMap> #include <QList> #include <QDateTime> #include <QDebug> QMap<int, QList<QDate>> splitDateTimeSlots(const QDateTime& startDateTime, const QDateTime& endDateTime) { QMap<int, QList<QDate>> dateTimeInSlots; const int slotsNum = 10; // 计算包含起止日期的总天数 const QDate startDate = startDateTime.date(); const QDate endDate = endDateTime.date(); const qint64 totalDays = startDate.daysTo(endDate) + 1; // 计算每组基础天数和余数 const qint64 baseDays = totalDays / slotsNum; qint64 remainder = totalDays % slotsNum; QDate currentStart = startDate; for (int i = 0; i < slotsNum; ++i) { QList<QDate> slotDates; // 无日期可分配时,分组为空 if (currentStart > endDate) { dateTimeInSlots[i+1] = slotDates; continue; } // 确定当前分组的结束日期 qint64 daysInSlot = baseDays; if (remainder > 0) { daysInSlot += 1; remainder--; } QDate currentEnd = currentStart.addDays(daysInSlot - 1); // 确保不超过结束日期边界 if (currentEnd > endDate) { currentEnd = endDate; } slotDates << currentStart << currentEnd; dateTimeInSlots[i+1] = slotDates; // 更新下一组的起始日期 currentStart = currentEnd.addDays(1); } return dateTimeInSlots; } int main() { QDateTime startDateTime(QDate(2023,6,10), QTime(0,0,0)); QDateTime endDateTime(QDate(2023,6,30), QTime(0,0,0)); QMap<int, QList<QDate>> dateTimeInSlots = splitDateTimeSlots(startDateTime, endDateTime); // 输出结果 for (const auto& key : dateTimeInSlots.keys()) { const auto& dates = dateTimeInSlots[key]; qDebug() << "Slot" << key << ":"; if (dates.isEmpty()) { qDebug() << "(Empty)"; } else { qDebug() << dates.first().toString("yyyy-MM-dd") << "to" << dates.last().toString("yyyy-MM-dd"); } qDebug() << "---------------------"; } return 0; }
修正说明
- 总天数计算修正:使用
startDate.daysTo(endDate) + 1,确保包含起止日期 - 简化日期处理:直接操作
QDate,避免时间部分干扰 - 余数分配优化:前
remainder组各多1天,保证分组均匀性 - 边界安全处理:当无日期可分配时,分组设为空,避免无效日期
- 移除冗余参数:删除未使用的
parsedDateTimeList参数
内容的提问来源于stack exchange,提问作者Melika
相关产品推荐
相关产品推荐

