File indexing completed on 2024-04-28 15:40:25

0001 // SPDX-FileCopyrightText: 2020 the KPhotoAlbum development team
0002 // SPDX-FileCopyrightText: 2022 - 2023 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
0003 //
0004 // SPDX-License-Identifier: GPL-2.0-or-later
0005 
0006 #ifndef UTILITIES_FASTDATETIME_H
0007 #define UTILITIES_FASTDATETIME_H
0008 #include <QDate>
0009 #include <QDateTime>
0010 #include <QDebug>
0011 #include <QTime>
0012 
0013 namespace Utilities
0014 {
0015 
0016 /**
0017  * The FastDateTime class implements a datetime that is much faster
0018  * than QDateTime for comparing dates.  It caches the linear time
0019  * since the epoch for use in comparisons.  See
0020  * https://bugreports.qt.io/browse/QTBUG-41714 and
0021  * https://bugreports.qt.io/browse/QTBUG-75585 for an explanation
0022  * of why the standard QDateTime is extremely slow (on the order of
0023  * 1 usec per comparison).
0024  *
0025  * The distinguished value INT64_MIN is used to indicate an invalid
0026  * date/time.  Invalid date/times are passed to QDateTime for handling.
0027  */
0028 
0029 class FastDateTime
0030 {
0031 public:
0032     FastDateTime();
0033     FastDateTime(const QDate &d, const QTime &t, Qt::TimeSpec spec = Qt::LocalTime);
0034     FastDateTime(const QDate &d);
0035     FastDateTime(const FastDateTime &other) = default;
0036     FastDateTime(FastDateTime &&other) = default;
0037     // Needed for QDate(Y, M, D).startOfDay()
0038     FastDateTime(const QDateTime &other);
0039     ~FastDateTime() {};
0040 
0041     Q_DECL_CONSTEXPR bool operator==(const FastDateTime &other) const
0042     {
0043         if (isOK() && other.isOK())
0044             return m_msecsSinceEpoch == other.m_msecsSinceEpoch;
0045         else
0046             return m_dateTime == other.m_dateTime;
0047     }
0048     Q_DECL_CONSTEXPR bool operator!=(const FastDateTime &other) const
0049     {
0050         if (isOK() && other.isOK())
0051             return m_msecsSinceEpoch != other.m_msecsSinceEpoch;
0052         else
0053             return m_dateTime != other.m_dateTime;
0054     }
0055     Q_DECL_CONSTEXPR bool operator<(const FastDateTime &other) const
0056     {
0057         if (isOK() && other.isOK())
0058             return m_msecsSinceEpoch < other.m_msecsSinceEpoch;
0059         else
0060             return m_dateTime < other.m_dateTime;
0061     }
0062     Q_DECL_CONSTEXPR bool operator<=(const FastDateTime &other) const
0063     {
0064         if (isOK() && other.isOK())
0065             return m_msecsSinceEpoch <= other.m_msecsSinceEpoch;
0066         else
0067             return m_dateTime <= other.m_dateTime;
0068     }
0069     Q_DECL_CONSTEXPR bool operator>(const FastDateTime &other) const
0070     {
0071         if (isOK() && other.isOK())
0072             return m_msecsSinceEpoch > other.m_msecsSinceEpoch;
0073         else
0074             return m_dateTime > other.m_dateTime;
0075     }
0076     Q_DECL_CONSTEXPR bool operator>=(const FastDateTime &other) const
0077     {
0078         if (isOK() && other.isOK())
0079             return m_msecsSinceEpoch >= other.m_msecsSinceEpoch;
0080         else
0081             return m_dateTime >= other.m_dateTime;
0082     }
0083     bool isNull() const { return m_dateTime.isNull(); }
0084     bool isValid() const { return m_dateTime.isValid(); }
0085     QDate date() const { return m_dateTime.date(); }
0086     QTime time() const { return m_dateTime.time(); }
0087     QString toString(Qt::DateFormat format = Qt::TextDate) const { return m_dateTime.toString(format); }
0088     QString toString(QStringView format) const
0089     {
0090         return m_dateTime.toString(format);
0091     }
0092     qint64 secsTo(const FastDateTime &other) const
0093     {
0094         if (isOK() && other.isOK())
0095             return (other.m_msecsSinceEpoch - m_msecsSinceEpoch) / 1000;
0096         else
0097             return secsTo(other);
0098     }
0099     qint64 toSecsSinceEpoch() const
0100     {
0101         if (isOK())
0102             return m_msecsSinceEpoch / 1000;
0103         else
0104             return m_dateTime.toSecsSinceEpoch();
0105     }
0106     FastDateTime &operator=(const Utilities::FastDateTime &other) = default;
0107     FastDateTime &operator=(Utilities::FastDateTime &&other) = default;
0108 
0109     Q_REQUIRED_RESULT FastDateTime addDays(qint64 days) const;
0110     Q_REQUIRED_RESULT FastDateTime addMonths(qint64 months) const;
0111     Q_REQUIRED_RESULT FastDateTime addYears(qint64 years) const;
0112     Q_REQUIRED_RESULT FastDateTime addSecs(qint64 secs) const;
0113 
0114     static FastDateTime currentDateTime();
0115     static FastDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
0116 
0117 private:
0118     Q_DECL_CONSTEXPR bool isOK() const
0119     {
0120         return m_msecsSinceEpoch > INT64_MIN;
0121     }
0122     QDateTime m_dateTime;
0123     qint64 m_msecsSinceEpoch;
0124 };
0125 }
0126 
0127 QDebug operator<<(QDebug debug, const Utilities::FastDateTime &d);
0128 
0129 #endif /* UTILITIES_FASTDATETIME_H */
0130 
0131 // vi:expandtab:tabstop=4 shiftwidth=4: