File indexing completed on 2024-04-21 15:30:13

0001 /* This file is part of the KDE project
0002    Copyright (C) 2018 Jarosław Staniek <staniek@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #ifndef KDB_DATETIME_H
0021 #define KDB_DATETIME_H
0022 
0023 #include "kdb_export.h"
0024 
0025 #include <QDateTime>
0026 #include <QDebug>
0027 
0028 /**
0029  * Generic year constant based on extended ISO 8601 specification
0030  *
0031  * This class as well as KDbDate, KDbTime and KDbDateTime is used as a replacement for Qt date/time
0032  * value classes in case when invalid values have to be preserved. Without this, SQL parsers would
0033  * not function properly because they would loose information about mistyped constants.
0034  * The KDb* make it possible for the user to store the constants in SQL expressions and fix them
0035  * at later time.
0036  *
0037  * See this page for specifications of the date/time formats supported:
0038  * https://community.kde.org/Kexi/Plugins/Queries/SQL_Constants#Date_constants
0039  *
0040  * @since 3.2.0
0041  */
0042 class KDB_EXPORT KDbYear
0043 {
0044 public:
0045     /**
0046      * Specifies sign which is used to annotate year
0047      */
0048     enum class Sign {
0049         None,
0050         Plus,
0051         Minus
0052     };
0053 
0054     /**
0055      * Constructs year based on given sign and string
0056      *
0057      * Resulting year can be invalid but the string is always preserved.
0058      */
0059     KDbYear(Sign sign, const QByteArray &string) : m_sign(sign), m_string(string)
0060     {
0061     }
0062 
0063     /**
0064      * Constructs yea based on given string, with sign set to Sign::None
0065      *
0066      * Resulting year can be invalid but the string is always preserved.
0067      */
0068     explicit KDbYear(const QByteArray &string) : KDbYear(Sign::None, string)
0069     {
0070     }
0071 
0072     /**
0073      * Contructs a null year
0074      */
0075     KDbYear() : KDbYear(QByteArray())
0076     {
0077     }
0078 
0079     bool operator==(const KDbYear &other) const;
0080 
0081     inline bool operator!=(const KDbYear &other) const { return !operator==(other); }
0082 
0083     bool operator<(const KDbYear &other) const;
0084 
0085     inline bool operator<=(const KDbYear &other) const { return operator<(other) || operator==(other); }
0086 
0087     inline bool operator>=(const KDbYear &other) const { return !operator<(other); }
0088 
0089     inline bool operator>(const KDbYear &other) const { return !operator<=(other); }
0090 
0091     /**
0092      * Returns @c true if the year is valid
0093      *
0094      * Year is invalid if it is null or if the supplied string is invalid according to specification.
0095      */
0096     bool isValid() const;
0097 
0098     /**
0099      * Returns @c true if the year is null
0100      *
0101      * A year is null if its sign is equal to Sign::None and string is empty.
0102      */
0103     bool isNull() const;
0104 
0105     /**
0106      * Returns the sign which is used to annotate year
0107      */
0108     Sign sign() const { return m_sign; }
0109 
0110     QByteArray signString() const;
0111 
0112     /**
0113      * Returns the string representation of year value even if it is invalid
0114      */
0115     QByteArray yearString() const { return m_string; }
0116 
0117     /**
0118      * Returns entire year value (with sign) converted to string even if it is invalid
0119      */
0120     QByteArray toString() const;
0121 
0122     /**
0123      * Returns the integer year value as defined by extended ISO 8601
0124      *
0125      * 0 is returned for invalid year.
0126      */
0127     int toIsoValue() const;
0128 
0129     /**
0130      * Returns the integer year value as defined by the QDate API
0131      *
0132      * 0 is returned for invalid year.
0133      */
0134     int toQDateValue() const;
0135 
0136 private:
0137     std::tuple<int, bool> intValue() const;
0138 
0139     const Sign m_sign;
0140     const QByteArray m_string;
0141     int m_isoValue = -1; //!< Cached value for intValue(), -1 if the cache is missing
0142 };
0143 
0144 Q_DECLARE_METATYPE(KDbYear)
0145 
0146 //! Sends information about value @a sign to debug output @a dbg.
0147 KDB_EXPORT QDebug operator<<(QDebug dbg, KDbYear::Sign sign);
0148 
0149 //! Sends information about value @a year to debug output @a dbg.
0150 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbYear &year);
0151 
0152 /**
0153  * Generic date constant
0154  *
0155  * @since 3.2.0
0156  */
0157 class KDB_EXPORT KDbDate
0158 {
0159 public:
0160     KDbDate(const KDbYear &year, const QByteArray &monthString, const QByteArray &dayString)
0161         : m_year(year), m_monthString(monthString), m_dayString(dayString)
0162     {
0163     }
0164 
0165     /**
0166      * Constructs a null date
0167      */
0168     KDbDate() = default;
0169 
0170     bool operator==(const KDbDate &other) const;
0171 
0172     inline bool operator!=(const KDbDate &other) const { return !operator==(other); }
0173 
0174     bool operator<(const KDbDate &other) const;
0175 
0176     inline bool operator<=(const KDbDate &other) const { return operator<(other) || operator==(other); }
0177 
0178     inline bool operator>=(const KDbDate &other) const { return !operator<(other); }
0179 
0180     inline bool operator>(const KDbDate &other) const { return !operator<=(other); }
0181 
0182     /**
0183      * Returns @c true if the date is valid
0184      *
0185      * Validation is performed by converting to QDate (toQDate()) and checking if it is valid.
0186      */
0187     bool isValid() const;
0188 
0189     /**
0190      * Returns @c true if the date is null
0191      *
0192      * A date is null if its year is null, month string is empty and date string is empty.
0193      */
0194     bool isNull() const;
0195 
0196     /**
0197      * Returns the date converted to QDate value
0198      *
0199      * Invalid QDate is returned if the KDbDate is invalid.
0200      */
0201     QDate toQDate() const;
0202 
0203     /**
0204      * Returns the date value converted to string even if it is invalid
0205      *
0206      * For null dates empty string is returned.
0207      */
0208     QByteArray toString() const;
0209 
0210     /**
0211      * Returns the year part of the date
0212      */
0213     KDbYear year() const { return m_year; }
0214 
0215     /**
0216      * Returns the month part of the date converted to integer
0217      *
0218      * Correct values are in range 1..12, -1 is returned for invalid month.
0219      */
0220     int month() const;
0221 
0222     /**
0223      * Returns the month part of the date
0224      *
0225      * It is original string passed to the KDbDate object and may be invalid.
0226      */
0227     QByteArray monthString() const { return m_monthString; }
0228 
0229     /**
0230      * Returns the day part of the date converted to integer
0231      *
0232      * Correct values are in range 1..31, -1 is returned for invalid day.
0233      * THe date can be still invalid for valid integer, e.g. February 31st.
0234      */
0235     int day() const;
0236 
0237     /**
0238      * Returns the day part of the date
0239      *
0240      * It is original string passed to the KDbDate object and may be invalid.
0241      */
0242     QByteArray dayString() const { return m_dayString; }
0243 
0244 private:
0245     const KDbYear m_year;
0246     const QByteArray m_monthString;
0247     const QByteArray m_dayString;
0248 };
0249 
0250 Q_DECLARE_METATYPE(KDbDate)
0251 
0252 //! Sends information about value @a date to debug output @a dbg.
0253 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbDate &date);
0254 
0255 /**
0256  * Generic time constant
0257  *
0258  * @since 3.2.0
0259  */
0260 class KDB_EXPORT KDbTime
0261 {
0262 public:
0263     /**
0264      * Specifies hour period
0265      */
0266     enum class Period {
0267         None, //!< 2-hour time
0268         Am,   //!< AM, before noon
0269         Pm    //!< PM, after noon, before midnight
0270     };
0271 
0272     KDbTime(const QByteArray &hourString, const QByteArray &minuteString,
0273             const QByteArray &secondString = QByteArray(),
0274             const QByteArray &msecString = QByteArray(), Period period = Period::None)
0275         : m_hourString(hourString)
0276         , m_minuteString(minuteString)
0277         , m_secondString(secondString)
0278         , m_msecString(msecString)
0279         , m_period(period)
0280     {
0281     }
0282 
0283     /**
0284      * Constructs a null time
0285      */
0286     KDbTime() = default;
0287 
0288     bool operator==(const KDbTime &other) const;
0289 
0290     inline bool operator!=(const KDbTime &other) const { return !operator==(other); }
0291 
0292     bool operator<(const KDbTime &other) const;
0293 
0294     inline bool operator<=(const KDbTime &other) const { return operator<(other) || operator==(other); }
0295 
0296     inline bool operator>=(const KDbTime &other) const { return !operator<(other); }
0297 
0298     inline bool operator>(const KDbTime &other) const { return !operator<=(other); }
0299 
0300     /**
0301      * Returns @c true if the time is valid
0302      *
0303      * Validation is performed by converting to QTime (toQTime()) and checking if it is valid.
0304      */
0305     bool isValid() const;
0306 
0307     /**
0308      * Returns @c true if the time is null
0309      *
0310      * A time is null if its hour string or minute string is empty.
0311      */
0312     bool isNull() const;
0313 
0314     /**
0315      * Returns the time value converted to QTime type
0316      *
0317      * Invalid QTime is returned if the KDbTime is invalid.
0318      */
0319     QTime toQTime() const;
0320 
0321     /**
0322      * Returns the time value converted to string even if it is invalid
0323      *
0324      * For null times empty string is returned.
0325      */
0326     QByteArray toString() const;
0327 
0328     /**
0329      * Returns the hour part of the time converted to integer
0330      *
0331      * Correct values are in range 0..23 for None period, and 1..12 for Am and Pm periods.
0332      * -1 is returned for invalid hour.
0333      */
0334     int hour() const;
0335 
0336     /**
0337      * Returns the hour part of the date
0338      *
0339      * It is original string passed to the KDbTime object and may be invalid.
0340      */
0341     QByteArray hourString() const { return m_hourString; }
0342 
0343     /**
0344      * Returns the minute part of the time converted to integer
0345      *
0346      * Correct values are in range 0..59. -1 is returned for invalid minute.
0347      */
0348     int minute() const;
0349 
0350     /**
0351      * Returns the minute part of the date
0352      *
0353      * It is original string passed to the KDbTime object and may be invalid.
0354      */
0355     QByteArray minuteString() const { return m_minuteString; }
0356 
0357     /**
0358      * Returns the second part of the time converted to integer
0359      *
0360      * Correct values are in range 0..59. -1 is returned for invalid second.
0361      */
0362     int second() const;
0363 
0364     /**
0365      * Returns the second part of the date
0366      *
0367      * It is original string passed to the KDbTime object and may be invalid.
0368      */
0369     QByteArray secondString() const { return m_secondString; }
0370 
0371     int msec() const;
0372 
0373     /**
0374      * Returns the milliseconds part of the date
0375      *
0376      * It is original string passed to the KDbTime object and may be invalid.
0377      */
0378     QByteArray msecString() const { return m_msecString; }
0379 
0380     /**
0381      * Specifies hour period
0382      */
0383     Period period() const { return m_period; }
0384 
0385 private:
0386     const QByteArray m_hourString;
0387     const QByteArray m_minuteString;
0388     const QByteArray m_secondString;
0389     const QByteArray m_msecString;
0390     const Period m_period = Period::None;
0391 };
0392 
0393 Q_DECLARE_METATYPE(KDbTime)
0394 
0395 //! Sends information about value @a time to debug output @a dbg.
0396 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbTime &time);
0397 
0398 /**
0399  * Generic date/time constant
0400  *
0401  * @since 3.2.0
0402  */
0403 class KDB_EXPORT KDbDateTime
0404 {
0405 public:
0406     KDbDateTime(const KDbDate &date, const KDbTime &time) : m_date(date), m_time(time)
0407     {
0408     }
0409 
0410     /**
0411      * Constructs a null date/time
0412      */
0413     KDbDateTime() : KDbDateTime(KDbDate(), KDbTime())
0414     {
0415     }
0416 
0417     bool operator==(const KDbDateTime &other) const;
0418 
0419     inline bool operator!=(const KDbDateTime &other) const { return !operator==(other); }
0420 
0421     bool operator<(const KDbDateTime &other) const;
0422 
0423     inline bool operator<=(const KDbDateTime &other) const { return operator<(other) || operator==(other); }
0424 
0425     inline bool operator>=(const KDbDateTime &other) const { return !operator<(other); }
0426 
0427     inline bool operator>(const KDbDateTime &other) const { return !operator<=(other); }
0428 
0429     /**
0430      * Returns @c true if the date/time is valid
0431      *
0432      * Validation is performed by converting to QDateTime (toQDateTime()) and checking if it is valid.
0433      */
0434     bool isValid() const;
0435 
0436     /**
0437      * Returns @c true if the date/time is null
0438      *
0439      * A time is null if its date or time is null.
0440      */
0441     bool isNull() const;
0442 
0443     /**
0444      * Returns the date/time converted to QDateTime value
0445      *
0446      * Invalid QDateTime is returned if the KDbDateTime is invalid.
0447      */
0448     QDateTime toQDateTime() const;
0449 
0450     /**
0451      * Returns the date/time value converted to string even if it is invalid
0452      *
0453      * For null date/times empty string is returned.
0454      */
0455     QByteArray toString() const;
0456 
0457     /**
0458      * Returns the date part of the date/time
0459      */
0460     KDbDate date() const { return m_date; }
0461 
0462     /**
0463      * Returns the time part of the date/time
0464      */
0465     KDbTime time() const { return m_time; }
0466 
0467 private:
0468     const KDbDate m_date;
0469     const KDbTime m_time;
0470 };
0471 
0472 Q_DECLARE_METATYPE(KDbDateTime)
0473 
0474 //! Sends information about value @a dateTime to debug output @a dbg.
0475 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbDateTime &dateTime);
0476 
0477 #endif