• QTime的本质上是一个int,QDateTime本质上是一个qint64


    研究这个问题的起因发现使用<=比较时间的不准确,所以怀疑是一个浮点数(Delphi里的time就是一个浮点数)。结果却发现是一个int

    class Q_CORE_EXPORT QTime
    {
        explicit Q_DECL_CONSTEXPR QTime(int ms) : mds(ms)
    #if defined(Q_OS_WINCE)
            , startTick(NullTime)
    #endif
        {}
    public:
        Q_DECL_CONSTEXPR QTime(): mds(NullTime)
    #if defined(Q_OS_WINCE)
            , startTick(NullTime)
    #endif
        {}
        QTime(int h, int m, int s = 0, int ms = 0);
    
        Q_DECL_CONSTEXPR bool isNull() const { return mds == NullTime; }
        bool isValid() const;
    
        int hour() const;
        int minute() const;
        int second() const;
        int msec() const;
    #ifndef QT_NO_DATESTRING
        QString toString(Qt::DateFormat f = Qt::TextDate) const;
        QString toString(const QString &format) const;
    #endif
        bool setHMS(int h, int m, int s, int ms = 0);
    
        QTime addSecs(int secs) const Q_REQUIRED_RESULT;
        int secsTo(const QTime &) const;
        QTime addMSecs(int ms) const Q_REQUIRED_RESULT;
        int msecsTo(const QTime &) const;
    
        Q_DECL_CONSTEXPR bool operator==(const QTime &other) const { return mds == other.mds; }
        Q_DECL_CONSTEXPR bool operator!=(const QTime &other) const { return mds != other.mds; }
        Q_DECL_CONSTEXPR bool operator< (const QTime &other) const { return mds <  other.mds; }
        Q_DECL_CONSTEXPR bool operator<=(const QTime &other) const { return mds <= other.mds; }
        Q_DECL_CONSTEXPR bool operator> (const QTime &other) const { return mds >  other.mds; }
        Q_DECL_CONSTEXPR bool operator>=(const QTime &other) const { return mds >= other.mds; }
    
        static Q_DECL_CONSTEXPR inline QTime fromMSecsSinceStartOfDay(int msecs) { return QTime(msecs); }
        Q_DECL_CONSTEXPR inline int msecsSinceStartOfDay() const { return mds == NullTime ? 0 : mds; }
    
        static QTime currentTime();
    #ifndef QT_NO_DATESTRING
        static QTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
        static QTime fromString(const QString &s, const QString &format);
    #endif
        static bool isValid(int h, int m, int s, int ms = 0);
    
        void start();
        int restart();
        int elapsed() const;
    private:
        enum TimeFlag { NullTime = -1 };
        Q_DECL_CONSTEXPR inline int ds() const { return mds == -1 ? 0 : mds; }
        int mds;
    #if defined(Q_OS_WINCE)
        int startTick;
    #endif
    
        friend class QDateTime;
        friend class QDateTimePrivate;
    #ifndef QT_NO_DATASTREAM
        friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QTime &);
        friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QTime &);
    #endif
    };

    但是整数的比较,为什么会不准确呢?不是很理解。。。非得减去一秒之后,比较才准确。让我再想想。。。

    看到里面有一个QDateTimePrivate,略加研究之后发现

    同时还在qdatetime.h里发现它使用了QDateTimePrivate,搜索之后(不在磁盘上搜索,只能看到它在qdatetime.h里有一个预定义class QDateTimePrivate),发现它定义在
    C:QtQt5.6.25.6mingw49_32includeQtCore5.6.2QtCoreprivateqdatetime_p.h
    C:QtQt5.6.25.6Srcqtbasesrccorelib oolsqdatetime.cpp

    而不存在qdateime_p.cpp文件。

    在qdatetime_p.h里发现如下定义:

    class QDateTimePrivate : public QSharedData
    {
    public:
        // Never change or delete this enum, it is required for backwards compatible
        // serialization of QDateTime before 5.2, so is essentially public API
        enum Spec {
            LocalUnknown = -1,
            LocalStandard = 0,
            LocalDST = 1,
            UTC = 2,
            OffsetFromUTC = 3,
            TimeZone = 4
        };
    
        // Daylight Time Status
        enum DaylightStatus {
            NoDaylightTime = -2,
            UnknownDaylightTime = -1,
            StandardTime = 0,
            DaylightTime = 1
        };
    
        // Status of date/time
        enum StatusFlag {
            NullDate            = 0x01,
            NullTime            = 0x02,
            ValidDate           = 0x04, // just the date field
            ValidTime           = 0x08, // just the time field
            ValidDateTime       = 0x10, // the whole object (including timezone)
            SetToStandardTime   = 0x40,
            SetToDaylightTime   = 0x80
        };
        Q_DECLARE_FLAGS(StatusFlags, StatusFlag)
    
        QDateTimePrivate() : m_msecs(0),
                             m_spec(Qt::LocalTime),
                             m_offsetFromUtc(0),
                             m_status(NullDate | NullTime)
        {}
    
        QDateTimePrivate(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec,
                         int offsetSeconds);
    
    #ifndef QT_BOOTSTRAPPED
        QDateTimePrivate(const QDate &toDate, const QTime &toTime, const QTimeZone & timeZone);
    #endif // QT_BOOTSTRAPPED
    
        // ### XXX: when the tooling situation improves, look at fixing the padding.
        // 4 bytes padding
    
        qint64 m_msecs;
        Qt::TimeSpec m_spec;
        int m_offsetFromUtc;
    #ifndef QT_BOOTSTRAPPED
        QTimeZone m_timeZone;
    #endif // QT_BOOTSTRAPPED
        StatusFlags m_status;
    
        void setTimeSpec(Qt::TimeSpec spec, int offsetSeconds);
        void setDateTime(const QDate &date, const QTime &time);
        QPair<QDate, QTime> getDateTime() const;
    
        void setDaylightStatus(DaylightStatus status);
        DaylightStatus daylightStatus() const;
    
        // Returns msecs since epoch, assumes offset value is current
        inline qint64 toMSecsSinceEpoch() const;
    
        void checkValidDateTime();
        void refreshDateTime();
    
        // Get/set date and time status
        inline bool isNullDate() const { return m_status & NullDate; }
        inline bool isNullTime() const { return m_status & NullTime; }
        inline bool isValidDate() const { return m_status & ValidDate; }
        inline bool isValidTime() const { return m_status & ValidTime; }
        inline bool isValidDateTime() const { return m_status & ValidDateTime; }
        inline void setValidDateTime() { m_status |= ValidDateTime; }
        inline void clearValidDateTime() { m_status &= ~ValidDateTime; }
        inline void clearSetToDaylightStatus() { m_status &= ~(SetToStandardTime | SetToDaylightTime); }
    
    #ifndef QT_BOOTSTRAPPED
        static qint64 zoneMSecsToEpochMSecs(qint64 msecs, const QTimeZone &zone,
                                            QDate *localDate = 0, QTime *localTime = 0);
    #endif // QT_BOOTSTRAPPED
    
        static inline qint64 minJd() { return QDate::minJd(); }
        static inline qint64 maxJd() { return QDate::maxJd(); }
    };

    可见的此时又变成了一个qint64,它可能是QDateTime要用到的数据。于是又看了一下qdatetime的定义:

    class QDateTimePrivate;
    
    class Q_CORE_EXPORT QDateTime
    {
    public:
        QDateTime();
        explicit QDateTime(const QDate &);
        QDateTime(const QDate &, const QTime &, Qt::TimeSpec spec = Qt::LocalTime);
        // ### Qt 6: Merge with above with default offsetSeconds = 0
        QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds);
    #ifndef QT_BOOTSTRAPPED
        QDateTime(const QDate &date, const QTime &time, const QTimeZone &timeZone);
    #endif // QT_BOOTSTRAPPED
        QDateTime(const QDateTime &other);
        ~QDateTime();
    
    #ifdef Q_COMPILER_RVALUE_REFS
        QDateTime &operator=(QDateTime &&other) Q_DECL_NOTHROW { swap(other); return *this; }
    #endif
        QDateTime &operator=(const QDateTime &other);
    
        void swap(QDateTime &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
    
        bool isNull() const;
        bool isValid() const;
    
        QDate date() const;
        QTime time() const;
        Qt::TimeSpec timeSpec() const;
        int offsetFromUtc() const;
    #ifndef QT_BOOTSTRAPPED
        QTimeZone timeZone() const;
    #endif // QT_BOOTSTRAPPED
        QString timeZoneAbbreviation() const;
        bool isDaylightTime() const;
    
        qint64 toMSecsSinceEpoch() const;
        // ### Qt 6: use quint64 instead of uint
        uint toTime_t() const;
    
        void setDate(const QDate &date);
        void setTime(const QTime &time);
        void setTimeSpec(Qt::TimeSpec spec);
        void setOffsetFromUtc(int offsetSeconds);
    #ifndef QT_BOOTSTRAPPED
        void setTimeZone(const QTimeZone &toZone);
    #endif // QT_BOOTSTRAPPED
        void setMSecsSinceEpoch(qint64 msecs);
        // ### Qt 6: use quint64 instead of uint
        void setTime_t(uint secsSince1Jan1970UTC);
    
    #ifndef QT_NO_DATESTRING
        QString toString(Qt::DateFormat f = Qt::TextDate) const;
        QString toString(const QString &format) const;
    #endif
        QDateTime addDays(qint64 days) const Q_REQUIRED_RESULT;
        QDateTime addMonths(int months) const Q_REQUIRED_RESULT;
        QDateTime addYears(int years) const Q_REQUIRED_RESULT;
        QDateTime addSecs(qint64 secs) const Q_REQUIRED_RESULT;
        QDateTime addMSecs(qint64 msecs) const Q_REQUIRED_RESULT;
    
        QDateTime toTimeSpec(Qt::TimeSpec spec) const;
        inline QDateTime toLocalTime() const { return toTimeSpec(Qt::LocalTime); }
        inline QDateTime toUTC() const { return toTimeSpec(Qt::UTC); }
        QDateTime toOffsetFromUtc(int offsetSeconds) const;
    #ifndef QT_BOOTSTRAPPED
        QDateTime toTimeZone(const QTimeZone &toZone) const;
    #endif // QT_BOOTSTRAPPED
    
        qint64 daysTo(const QDateTime &) const;
        qint64 secsTo(const QDateTime &) const;
        qint64 msecsTo(const QDateTime &) const;
    
        bool operator==(const QDateTime &other) const;
        inline bool operator!=(const QDateTime &other) const { return !(*this == other); }
        bool operator<(const QDateTime &other) const;
        inline bool operator<=(const QDateTime &other) const { return !(other < *this); }
        inline bool operator>(const QDateTime &other) const { return other < *this; }
        inline bool operator>=(const QDateTime &other) const { return !(*this < other); }
    
    #if QT_DEPRECATED_SINCE(5, 2)
        QT_DEPRECATED void setUtcOffset(int seconds);
        QT_DEPRECATED int utcOffset() const;
    #endif // QT_DEPRECATED_SINCE
    
        static QDateTime currentDateTime();
        static QDateTime currentDateTimeUtc();
    #ifndef QT_NO_DATESTRING
        static QDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
        static QDateTime fromString(const QString &s, const QString &format);
    #endif
        // ### Qt 6: use quint64 instead of uint
        static QDateTime fromTime_t(uint secsSince1Jan1970UTC);
        // ### Qt 6: Merge with above with default spec = Qt::LocalTime
        static QDateTime fromTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec,
                                    int offsetFromUtc = 0);
    #ifndef QT_BOOTSTRAPPED
        static QDateTime fromTime_t(uint secsSince1Jan1970UTC, const QTimeZone &timeZone);
    #endif
        static QDateTime fromMSecsSinceEpoch(qint64 msecs);
        // ### Qt 6: Merge with above with default spec = Qt::LocalTime
        static QDateTime fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetFromUtc = 0);
    #ifndef QT_BOOTSTRAPPED
        static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone);
    #endif
        static qint64 currentMSecsSinceEpoch() Q_DECL_NOTHROW;
    
    #if defined(Q_OS_MAC) || defined(Q_QDOC)
        static QDateTime fromCFDate(CFDateRef date);
        CFDateRef toCFDate() const Q_DECL_CF_RETURNS_RETAINED;
    #  if defined(__OBJC__) || defined(Q_QDOC)
        static QDateTime fromNSDate(const NSDate *date);
        NSDate *toNSDate() const Q_DECL_NS_RETURNS_AUTORELEASED;
    #  endif
    #endif
    
    private:
        friend class QDateTimePrivate;
    
        // ### Qt6: Using a private here has high impact on runtime
        // on users such as QFileInfo. In Qt 6, the data members
        // should be inlined.
        QSharedDataPointer<QDateTimePrivate> d;
    
    #ifndef QT_NO_DATASTREAM
        friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &);
        friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &);
    #endif
    
    #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
        friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &);
    #endif
    };
    Q_DECLARE_SHARED(QDateTime)

    其中最关键的是<操作符的比较,它代表了使用的真正数据,而且其它几个比较函数实质上都依赖这个操作符:

    bool QDateTime::operator<(const QDateTime &other) const
    {
        if (d->m_spec == Qt::LocalTime
            && other.d->m_spec == Qt::LocalTime
            && d->m_status == other.d->m_status) {
            return (d->m_msecs < other.d->m_msecs);
        }
        // Convert to UTC and compare
        return (toMSecsSinceEpoch() < other.toMSecsSinceEpoch());
    }

    其中最关键的是toMSecsSinceEpoch函数,结果发现如下定义:

        qint64 toMSecsSinceEpoch() const;

    可见的QDateTime本质上是一个qint64

  • 相关阅读:
    从零开始入门 K8s | 应用编排与管理
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    203. Remove Linked List Elements
    183. Customers Who Never Order
    182. Duplicate Emails
    181. Employees Earning More Than Their Managers
    1261. Find Elements in a Contaminated Binary Tree
    1260. Shift 2D Grid
  • 原文地址:https://www.cnblogs.com/findumars/p/7202590.html
Copyright © 2020-2023  润新知