QT6 源(85):阅读与注释日期时间类型 QDateTime,源代码以及属性测试,并附上包含 QDate、QTime、 QDateTime 定义的头文件 qdatetime . h

(1)

在这里插入图片描述

(2) 此图说明不必学习 utc 时间,学习本地时间就够,也便于测试

在这里插入图片描述

(3)

在这里插入图片描述

(4)

在这里插入图片描述

++
在这里插入图片描述

(5)

在这里插入图片描述

++ 测试举例

在这里插入图片描述

(6)给出源代码,来自于头文件 qdatetime . h

/*
UTC是时间标准,确保全球时间同步。
Epoch是基于UTC的时间起点,为计算机系统提供统一的时间计算基准。
二者结合使得时间戳成为跨平台、跨时区的通用时间表示方法,广泛应用于编程、网络通信、安全等领域。

在计算机科学中,Epoch通常指一个固定的时间起点,最经典的例子是Unix时间戳的Epoch:
定义:Unix时间戳的Epoch定义为1970年1月1日00:00:00 UTC,之后的每一秒用一个整数表示。

最经典的是Unix时间戳的Epoch,即1970年1月1日00:00:00 UTC。
作用:作为时间计算的参考点,所有时间戳均基于此点计算经过的秒数(或毫秒数)。

总之, utc 是有用的时间参考系,其及时起点就是 epoch,对应于时间 1970年1月1日00:00:00 UTC
*/

/*
The QDateTime class provides date and time functions.

QDateTime 对象编码日历日期和时钟时间(一个“datetime”)。它结合了 QDate 和QTime类的功能。
它可以从系统时钟读取当前 datetime。它提供了比较 datetimes 和通过添加秒数、天数、月数或年数
来操作 datetime 的函数。

QDateTime可以与QTimeZone类一起描述相对于本地时间、UTC、相对于UTC的指定偏移量或特定时区的日期和时间。
例如,“Europe/Berlin”时区将应用德国使用的夏令时规则。
相比之下,相对于UTC的+3600秒的偏移量比UTC早一小时(通常以ISO标准表示为“UTC+01:00”),
没有夏令时偏移或变化。
在使用本地时间或特定时区时,会考虑时区的转换,例如夏令时的开始和结束(DST;但请参见下文)。
用于表示日期时间系统的选择称为其“timespec”。

通常,可以通过在构造函数中显式提供日期和时间,
或者使用静态函数(如currentDateTime()或fromMSecsSinceEpoch())来创建一个QDateTime对象。
可以通过setDate()和setTime(来更改日期和时间。
还可以使用setMSecsSinceEpoch()函数来设置日期和时间,该函数接受自1970年1月1日00:00:00的毫秒数。
从String()函数返回一个QDateTime,给定一个字符串和一个用于解释字符串中日期的日期格式。

QDateTime::currentDateTime   ()返回一个 QDateTime,它表示相对于本地时间的当前时间。
QDateTime::currentDateTimeUtc()返回一个 QDateTime,  表示相对于UTC的当前时间。
date()和time()函数提供对 datetime中的日期和时间的访问。toString()函数以文本格式提供相同的信息。
QDateTime提供了一整套运算符来比较两个QDateTime对象,其中较小的表示较早,较大的表示较晚.

您可以使用addMSecs()函数将datetime增加(或减少)给定数量的毫秒,
使用addSecs函数将datetime增加或减少给定数量的秒,
使用addDays()函数将datetime增加或减少给定的天数。
同样,您可以使用addMonths()和addYears()函数。
daysTo()函数返两个datetime之间的天数,secsTo()函数返回两个datetime之间的秒数,
msecsTo()函数返回两个datetime之间的毫秒数。这些操作在适用的情况下考虑到夏令时和其他时区转换.
使用  toTimeSpec()      以本地时间或UTC表示一个日期时间,
使用  to0ffsetFromUtc() 以UTC的偏移量表示,
或使用toTimeZone()      以一般时区表示。

您可以使用 timeSpec() 来查找QDateTime对象存储其时间相对于的 timeSpec。
当该值为 Qt:TimeZone时,您可以使用timeZone()、来查找它正在使用的时区。
意思是先 timeSpec,后时区 timeZone。
//enum Qt::TimeSpec { LocalTime, UTC, OffsetFromUTC, TimeZone };

注:QDateTime不考虑闰秒。
Note: All conversion to and from string formats is done using the C locale.

注:格里高利历中没有公元0年。该年的日期被认为无效
。公元-1年是“公元前1年或“公历前1年”。公元1年1月1日的前一天是公元前31年12月31日。

Range of Valid Dates:
QDateTime可以表示的值范围取决于内部存储实现。
QDateTime目前以gint64的形式存储,作为表示日期和时间的序列msecs值。
这限制了日期范围约为士2.92亿年而QDate的范围为士20亿年。
在创建具有极端值的QDateTime时,必须小心,以免溢出存储。
支持的值的确切范围因Ot::Timespec和时区而异。

Use of Timezones:
QDateTime 使用系统的时区信息来确定当前本地时区及其相对于UTC的偏移量。
如果系统配置不正确或未更新,QDateTime将给出错误的结果。
QDateTime 同样使用系统提供的信息来确定其他时区相对于 UTC的偏移量。
如果这些信息不完整或过时,QDateTime 将会给出错误的结果。请参阅 QTimeZone 文档以获取更多信息。
在现代的Unix系统中,这意味着QDateTime通常具有关于历史转换(包括DST见下文)的准确信息,只要有可能。
在Windows上,系统不支持历史时区数据,因此历史准确性在时区转换方面没有得到维护,特别是包括DST。

Daylight-Saving Time (DST):
QDateTime 考虑了标准时间和夏令时之间的转换。
例如,如果转换发生在凌晨2点,时钟向前跳到3点,
那么从02:00:00到02:59:59.999之间就有一个“缺失”小时,QDateTime认为这个小时是无效的。
执行的任何日期运算都会考虑到这个缺失小时并返回有效结果。例如,将1分钟加到01:59:59将得到03:00:00。

对干系统时间 time_t可以表示的日期和时间
(在32位时间t的系统上为1901-12-14到2038-01-18:如果类型为64位,则ODateTime可以表示整个范围),
使用标准系统API来确定本地时间相对于UTC的偏移量。
对于这些系统API未处理的日期和时间,使用0TimeZone::svstemTimeZone()函数。
无论哪种情况,使用的偏移信息都取决于系统,并且可能不完整,
或者对于过去的日期,历史上可能不准确。
在任何情况下,对于未来的日期,本地时区的偏移量和夏令时规则在该日期到来之前可能会发生变化。

Offsets From UTC:
对于从UTC开始的偏移量,没有明确的尺寸限制,
但当使用使用【+l-】hh:mm格式的toString()和fromString()方法时,会施加一个隐含的限制,
有效地将范围限制在+/-99小时和59分钟以及整分钟。
请注意,目前没有时区的偏移量超出土14小时的范围,所有已知的偏移量都是5分钟的倍数。

*/

class Q_CORE_EXPORT QDateTime
{
private:
    bool equals  (const QDateTime & other) const;
    bool precedes(const QDateTime & other) const;

    friend bool operator==(const QDateTime & lhs, const QDateTime & rhs)
    { return lhs.equals(rhs); }

    friend bool operator!=(const QDateTime & lhs, const QDateTime & rhs)
    { return !(lhs == rhs); }

    friend bool operator< (const QDateTime & lhs, const QDateTime & rhs)
    { return lhs.precedes(rhs); }

    friend bool operator<=(const QDateTime & lhs, const QDateTime & rhs)
    { return !(rhs < lhs); }

    friend bool operator> (const QDateTime & lhs, const QDateTime & rhs)
    { return rhs.precedes(lhs); }

    friend bool operator>=(const QDateTime & lhs, const QDateTime & rhs)
    { return !(lhs < rhs); }

    friend Q_CORE_EXPORT QDataStream & operator<<(QDataStream &, const QDateTime &);
    friend Q_CORE_EXPORT QDataStream & operator>>(QDataStream &,       QDateTime &);
    friend Q_CORE_EXPORT QDebug        operator<<(QDebug       , const QDateTime &);


    struct ShortData //短数据
    {
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN //确实是小端法
        quintptr status : 8;
#endif

#if QT_VERSION   >= QT_VERSION_CHECK(7,0,0)
        qint64 msecs : 56;
#else
        // note: this is only 24 bits on 32-bit systems...
        qintptr msecs : sizeof(void *) * 8 - 8;
#endif

#if Q_BYTE_ORDER == Q_BIG_ENDIAN   //这里存在大端小端的颠倒顺序
        quintptr status : 8;
#endif
    };

    friend class QDateTimePrivate; //下面要用

    union Data { //无官方注释
        enum {
            // To be of any use, we need at least 60 years around 1970,
            //      which is 1,893,456,000,000 ms.
            // That requires 41 bits to store, plus the sign bit.
            //      With the status byte, the minimum size is 50 bits.
            //为了有用,我们至少需要在1970年左右存储60年,即1,893,456,000,000毫秒。
            //这需要41位来存储,再加上符号位。使用状态字节,最小大小为50位。
            CanBeSmall = sizeof(ShortData) * 8 > 50 //可见这是个布尔量 0 或 1
        };

        Data() noexcept;
        Data(Qt::TimeSpec);
        //enum Qt::TimeSpec { LocalTime, UTC, OffsetFromUTC, TimeZone };

        Data(const Data &  other);
        Data(      Data && other);

        Data & operator=(const Data & other);

        ~Data();

        bool isShort() const;
        void detach();

        const QDateTimePrivate * operator->() const;
              QDateTimePrivate * operator->();

        QDateTimePrivate * d   ; //本类的数据成员
        ShortData          data; //又一个数据成员
    };
    Data d; //本 QDateTime类的数据成员

public:
    // (1<<63) ms is 292277024.6 (average Gregorian) years,  格里高利历法
    //counted from the start of 1970, so Last is floor(1970 + 292277024.6);
    //no year 0, so First is floor(1970 - 1 - 292277024.6) //有效年份的取值范围
    enum class YearRange : qint32 { First = -292275056,  Last = +292278994 };

    //Constructs a null datetime.
    //A null datetime is invalid, since its date and time are invalid.
    QDateTime() noexcept;

    //Constructs a datetime with the given date and time,
    //using the Time Zone specified by timeZone.
    //If date is valid and time is not, the time will be set to 00:00:00.
    //If timeZone is invalid then the datetime will be invalid.
    QDateTime(QDate date, QTime time, const QTimeZone &  timeZone);

    //enum Qt::TimeSpec { LocalTime, UTC, OffsetFromUTC, TimeZone };
    QDateTime(QDate date, QTime time,   Qt::TimeSpec     spec = Qt::LocalTime,
                                                int offsetSeconds = 0);
    //Constructs a datetime with the given date and time,
    //using the time specification defined by spec and offsetSeconds seconds.
    //If date is valid and time is not, the time will be set to midnight.
    //If the spec is not Qt::OffsetFromUTC then offsetSeconds will be ignored.
    //If the spec is Qt::OffsetFromUTC and offsetSeconds is 0 then the
    //timeSpec() will be set to Qt::UTC, i.e. an offset of 0 seconds.
    //If spec is Qt::TimeZone then the spec will be set to Qt::LocalTime,
    //                                      i.e. the current system time zone.
    //To create a Qt::TimeZone datetime use the correct constructor.

    QDateTime(const QDateTime &  other) noexcept; //copy构造函数

    QDateTime(      QDateTime && other) noexcept; //移动构造函数

    ~QDateTime();

    QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QDateTime) //移动赋值运算符函数
/*
#define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Class) \
    Class & operator=(Class && other) noexcept { \
        swap(other); \
        return *this; \
    }
*/

    QDateTime & operator=(const QDateTime & other) noexcept; //copy赋值运算符函数

    void swap(QDateTime & other) noexcept { qSwap(d.d, other.d.d); }

    //Returns a QDateTime object containing a
    //   datetime msecs milliseconds later than the datetime of this object
    //(or earlier if msecs is negative).
    //If this datetime is invalid, an invalid datetime will be returned.
    [[nodiscard]] QDateTime addMSecs (qint64  msecs ) const;
    [[nodiscard]] QDateTime addSecs  (qint64  secs  ) const;
    [[nodiscard]] QDateTime addDays  (qint64  days  ) const;
    [[nodiscard]] QDateTime addMonths(int     months) const;
    [[nodiscard]] QDateTime addYears (int     years ) const;

    //Returns the current datetime,
    //as reported by the system clock, in the local time zone.
    static  QDateTime    currentDateTime   ();
    //QDateTime(2025-05-08 07:14:53.454 中国标准时间 Qt::LocalTime)
    //QDateTime(2025-05-07 23:14:53.469 UTC Qt::UTC) //如此大的差异,不再学习 UTC时间了!!
    static  QDateTime    currentDateTimeUtc();
    //Returns the current datetime, as reported by the system clock, in UTC.


    static  qint64       currentSecsSinceEpoch() noexcept;
    static  QDateTime       fromSecsSinceEpoch(qint64 secs,
                                        Qt::TimeSpec spec = Qt::LocalTime,
                                        int offsetFromUtc = 0);
    static  QDateTime       fromSecsSinceEpoch(qint64 secs,
                                        const QTimeZone & timeZone);


    static  qint64       currentMSecsSinceEpoch() noexcept;
    static  QDateTime       fromMSecsSinceEpoch(qint64 msecs,
                                         Qt::TimeSpec spec = Qt::LocalTime,
                                         int offsetFromUtc = 0);
    static  QDateTime       fromMSecsSinceEpoch(qint64 msecs,
                                         const QTimeZone & timeZone);


    //enum Qt::TimeSpec { LocalTime, UTC, OffsetFromUTC, TimeZone };
    QDateTime toTimeSpec     (  Qt::TimeSpec    spec) const;

    //Returns a datetime containing the date and time information in this datetime,
    //but specified using the Qt::LocalTime definition.
    inline  QDateTime toLocalTime    () const
    { return  toTimeSpec(Qt::LocalTime); }

    inline  QDateTime toUTC          () const
    { return  toTimeSpec(Qt::UTC); }
    //Returns a datetime containing the date and time information in this datetime,
    //but specified using the Qt::UTC definition.

    QDateTime toOffsetFromUtc(     int          offsetSeconds) const;

    QDateTime toTimeZone     (const QTimeZone & toZone       ) const;

    bool isNull        () const;
    bool isValid       () const;
    bool isDaylightTime() const;
    //Returns if this datetime falls in Daylight-Saving Time.
    //If the Qt::TimeSpec is not Qt::LocalTime or Qt::TimeZone then will
    //always return false.

    //返回从当前日期时间到另一个日期时间的天数。
    //天数计算为从当前日期时间到另一个日期时间之间午夜到达的次数。
    //这意味着从23:55到第二天0:05的10分钟差异算作一天。
    //如果另一个日期时间早于此日期时间,则返回的值为负数。
    qint64  daysTo(const QDateTime &) const;
    qint64  secsTo(const QDateTime &) const;
    qint64 msecsTo(const QDateTime &) const;
    //返回从当前日期时间到另一个日期时间的毫秒数。如果另一个日期时间早于当前日期时间,则返回的值为负。
    //在进行比较之前,将两个日期时间转换为 Qt::UTC,
    //以确保如果两个日期时间中的一个适用夏令时(DST)而另一个不适用,则结果正确。
    //如果任一日期时间无效,则返回 0。

    QDate     date() const; //Returns the date part of the datetime.
    void   setDate(QDate date);
    //若时间值之前为 null则改为零时间值,否则此处会维持时间部分不变,即只改变日期。
    //Sets the date part of this datetime to date.
    //If no time is set yet, it is set to midnight.
    //If date is invalid, this QDateTime becomes invalid.

    QTime     time() const; //Returns the time part of the datetime.
    void   setTime(QTime time);
    //Sets the time part of this datetime to time.
    //If time is not valid, this function sets it to midnight.
    //Therefore, it's possible to clear any set time in a QDateTime by setting
    //it to a default QTime:

    QTimeZone        timeZone() const;
    void          setTimeZone(const QTimeZone & toZone);
    QString          timeZoneAbbreviation() const;


    //enum Qt::TimeSpec { LocalTime, UTC, OffsetFromUTC, TimeZone };
    Qt::TimeSpec     timeSpec() const;
    void          setTimeSpec(Qt::TimeSpec spec);

    int       offsetFromUtc() const; //utc 见20,是优秀的时间,但中国用 CST时间
    void   setOffsetFromUtc(int offsetSeconds);

    qint64    toSecsSinceEpoch() const;      //新纪元 Epoch
    void     setSecsSinceEpoch(qint64 secs);

    qint64   toMSecsSinceEpoch() const;
    void    setMSecsSinceEpoch(qint64 msecs);

    //enum Qt::DateFormat { TextDate, ISODate, RFC2822Date = 8, ISODateWithMs };
    QString toString(  Qt::DateFormat    format = Qt::TextDate) const;

    QString toString(      QStringView   format, QCalendar cal = QCalendar()) const;

    QString toString(const QString     & format, QCalendar cal = QCalendar()) const
    { return toString(qToStringViewIgnoringNull(format), cal); }


    static QDateTime fromString(const   QString      &  string,
                                const   QString      &  format, //默认公历
                                        QCalendar       cal = QCalendar())
    { return fromString(string, qToStringViewIgnoringNull(format), cal); }

    static QDateTime fromString(const   QString      &  string,
                                        QStringView     format,
                                        QCalendar       cal = QCalendar());

    static QDateTime fromString(const   QString      &  string,
                                    Qt::DateFormat      format = Qt::TextDate)
    { return fromString(qToStringViewIgnoringNull(string), format); }

    static QDateTime fromString(        QStringView     string,
                                    Qt::DateFormat      format = Qt::TextDate);

    static QDateTime fromString(        QStringView     string,
                                        QStringView     format,
                                        QCalendar       cal = QCalendar())
    { return fromString(string.toString(), format, cal); }


#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
    static QDateTime    fromCFDate(      CFDateRef    date);
           CFDateRef      toCFDate() const Q_DECL_CF_RETURNS_RETAINED;

           NSDate     *   toNSDate() const Q_DECL_NS_RETURNS_AUTORELEASED;
    static QDateTime    fromNSDate(const NSDate    *  date);
#endif

}; //完结 class QDateTime
Q_DECLARE_SHARED(QDateTime)

#ifndef QT_NO_DATASTREAM
Q_CORE_EXPORT QDataStream & operator<<(QDataStream &,       QDate      );
Q_CORE_EXPORT QDataStream & operator>>(QDataStream &,       QDate     &);

Q_CORE_EXPORT QDataStream & operator<<(QDataStream &,       QTime      );
Q_CORE_EXPORT QDataStream & operator>>(QDataStream &,       QTime     &);

Q_CORE_EXPORT QDataStream & operator<<(QDataStream &, const QDateTime &);
Q_CORE_EXPORT QDataStream & operator>>(QDataStream &,       QDateTime &);
#endif // QT_NO_DATASTREAM


Q_CORE_EXPORT QDebug operator<<(QDebug,       QDate      );
Q_CORE_EXPORT QDebug operator<<(QDebug,       QTime      );
Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &);


// QDateTime is not noexcept for now --
// to be revised once timezone and calendaring support is added
//QDateTime 目前不是 noexcept--一旦添加了时区和日历支持,将对其进行修订。
Q_CORE_EXPORT size_t qHash(const QDateTime & key, size_t seed = 0);
Q_CORE_EXPORT size_t qHash(      QDate       key, size_t seed = 0) noexcept;
Q_CORE_EXPORT size_t qHash(      QTime       key, size_t seed = 0) noexcept;

(7)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值