You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

修正说明

  1. 总天数计算修正:使用startDate.daysTo(endDate) + 1,确保包含起止日期
  2. 简化日期处理:直接操作QDate,避免时间部分干扰
  3. 余数分配优化:前remainder组各多1天,保证分组均匀性
  4. 边界安全处理:当无日期可分配时,分组设为空,避免无效日期
  5. 移除冗余参数:删除未使用的parsedDateTimeList参数

内容的提问来源于stack exchange,提问作者Melika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 02:54:52