zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    细说VMWare加入OpenStack
    云计算和大数据的崛起
    HTML5 Web app开发工具Kendo UI Web教程:如何配置Kendo UI Calendar
    Android:增强目录选择器对话框
    Gartner指明2014年几大战略技术趋势
    Android开发人员终于在“app-构建控制台”中获得分析
    谷歌升级Android分析应用程序
    Android是Windows开发人员可选择的下一个平台
    Greek
    为什么质数有无穷多个
  • 原文地址:https://www.cnblogs.com/findumars/p/7202590.html
Copyright © 2011-2022 走看看