File indexing completed on 2024-04-28 15:39:56

0001 /* SPDX-FileCopyrightText: 2003-2010 Jesper K. Pedersen <blackie@kde.org>
0002    SPDX-FileCopyrightText: 2023 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef IMAGEDATE_H
0008 #define IMAGEDATE_H
0009 #include <Utilities/FastDateTime.h>
0010 #include <QDebug>
0011 #include <qstring.h>
0012 #include <qstringlist.h>
0013 
0014 namespace DB
0015 {
0016 
0017 class ImageDate
0018 {
0019 public:
0020     /**
0021      * @brief Constructs a null ImageDate.
0022      */
0023     ImageDate();
0024     /**
0025      * @brief Constructs a fuzzy ImageDate with start and end date.
0026      * The ImageDate cover the time range from the beginning of start date to the end of the end date.
0027      *
0028      * Note: the ImageDate will always range from the earlier to the later date, even if parameters are swapped.
0029      *
0030      * @param start the start date
0031      * @param end the end date
0032      */
0033     ImageDate(const QDate &start, const QDate &end);
0034     /**
0035      * @brief Constructs a (fuzzy) ImageDate with the given start and end date/time.
0036      * The ImageDate covers the exact time range from the start date to the end date. If start date and end date are the same, the resulting ImageDate will not be fuzzy.
0037      *
0038      * Note: the ImageDate will always range from the earlier to the later date, even if parameters are swapped.
0039      *
0040      * @param start the start date/time
0041      * @param end the end date/time
0042      */
0043     ImageDate(const Utilities::FastDateTime &start, const Utilities::FastDateTime &end);
0044     ImageDate(int yearFrom, int monthFrom, int dayFrom, int yearTo, int monthTo, int dayTo, int hourFrom, int minuteFrom, int secondFrom);
0045     /**
0046      * @brief Constructs an ImageDate for the given QDate.
0047      * The resulting date will be a non-fuzzy date, i.e. the start and end time will both be the same (0:00:00).
0048      */
0049     explicit ImageDate(const QDate &);
0050     /**
0051      * @brief Constructs an ImageDate for the given date and time.
0052      * @param date the start and end date/time
0053      */
0054     explicit ImageDate(const Utilities::FastDateTime &date);
0055     /**
0056      * @brief Constructs an ImageDate.
0057      *
0058      * If start and end are the same, or if end is not a valid QDate, an ImageDate for start and time is constructed.
0059      * If start and end are not the same and are valid, then time is ignored and an ImageDate for start and end is constructed.
0060      *
0061      * @param start the start date
0062      * @param end the end date
0063      * @param time the start time, if end == start of if end is invalid
0064      */
0065     ImageDate(const QDate &start, const QDate &end, const QTime &time);
0066 
0067     const Utilities::FastDateTime &start() const { return m_start; }
0068     const Utilities::FastDateTime &end() const { return m_end; }
0069 
0070     /**
0071      * @brief operator <
0072      * @param other
0073      * @return \c true, if the ImageDate starts earlier than the other ImageDate, or the ImageDate starts at the same moment as the other one, but ends earlier. \c false otherwise
0074      */
0075     bool operator<(const ImageDate &other) const;
0076     /**
0077      * @brief operator <=
0078      * @param other
0079      * @return \c true, if the ImageDate starts earlier than the other ImageDate, or the ImageDate starts at the same moment as the other one, but does not end later. \c false otherwise
0080      */
0081     bool operator<=(const ImageDate &other) const;
0082     /**
0083      * @brief operator ==
0084      * @param other
0085      * @return \c true, if both ImageDates start and end at the same time, \c false otherwise
0086      */
0087     bool operator==(const ImageDate &other) const;
0088     /**
0089      * @brief operator !=
0090      * @param other
0091      * @return \c true, if the two ImageDates are not equal.
0092      */
0093     bool operator!=(const ImageDate &other) const;
0094 
0095     /**
0096      * @brief isValid
0097      * @return returns \c true, if the ImageDate has at least a valid start date, \c false if it is null.
0098      */
0099     bool isValid() const { return !isNull(); }
0100     /**
0101      * @brief isNull
0102      * @return returns \c true, if start() is null, \c true otherwise
0103      */
0104     bool isNull() const;
0105     /**
0106      * @brief isFuzzy
0107      * Calling isFuzzy() on an invalid ImageDate is undefined.
0108      * @return \c true, if start and end is not the same, \c false otherwise.
0109      */
0110     bool isFuzzy() const;
0111     /**
0112      * @brief toString returns a localized representation of the ImageDate.
0113      * @param withTime can be used to control whether the time is included.
0114      * @return a localized QString representing the ImageDate
0115      */
0116     QString toString(bool withTime = true) const;
0117     /**
0118      * @brief hasValidTime
0119      * @return \c true, if the time is meaningful, \c false if the ImageDate is fuzzy.
0120      */
0121     bool hasValidTime() const;
0122 
0123     /**
0124      * @brief The MatchType enum is used to qualify the result of ImageDate::isIncludedIn(const ImageDate &)
0125      */
0126     enum class MatchType {
0127         NoMatch, ///< The two ImageDates do not match.
0128         IsContained, ///< The ImageDate is fully contained within the range.
0129         Overlap ///< The two ImageDates do overlap.
0130     };
0131 
0132     /**
0133      * @brief isIncludedIn checks whether the ImageDate is contained within the given range.
0134      * @param searchRange a (fuzzy) ImageDate representing the date range
0135      * @return MatchType::IsContained, if the ImageDate is part of the searchRange; MatchType::Overlap, if the ImageDate is not part of the searchRange, but both ranges overlap; or otherwise MatchTape::NoMatch.
0136      */
0137     MatchType isIncludedIn(const ImageDate &searchRange) const;
0138     /**
0139      * @brief The ImageDate includes another, if its start() is not later than the other start(), and its end() is not earlier than the other end().
0140      * If the ImageDate is not fuzzy, this is the same as comparing both dates for equality ('==').
0141      * @param date an ImageDate
0142      * @return \c true, if the date is strictly withing this ImageDate
0143      */
0144     bool includes(const Utilities::FastDateTime &date) const;
0145 
0146     /**
0147      * @brief Extends the ImageDate to incorporate the other date, usually resulting in a fuzzy date.
0148      *
0149      * If the ImageDate is invalid, this is equivalent to setting it to the other date.
0150      * If the other ImageDate is invalid, nothing is changed.
0151      * @param other the other ImageDate
0152      */
0153     void extendTo(const ImageDate &other);
0154 
0155 private:
0156     Utilities::FastDateTime m_start, m_end;
0157 };
0158 
0159 /**
0160  * @brief DB::parseDateString parses a user-supplied string into a QDate.
0161  *
0162  * The dateString can be incomplete and the function will do its best to fill in the missing information.
0163  *
0164  * If \c assumeStartDate is \c true, the missing information is assumed to be the date to be at the
0165  * start of the imprecise time period (e.g. "2021" will be parsed as January 1st 2021). If \c assumeStartDate
0166  * is \c false, the missing information is assumed to be at the end of the imprecise time perion (e.g.
0167  * "2021" will be parsed as December 31st 2021).
0168  *
0169  * Years can be two-digit numbers. Two-digit years lower than 50 are interpreted as 20xx; other two digit years are interpreted as 19xx.
0170  * The general allowed format is:
0171  *  - day of month: a one-digit or two-digit number, possibly followed by any of '-', ',', '.', ' ', '/'
0172  *  - month: either a number between 1 and 12, or the full or appreviated name of the month (in English or in the current locale), possibly followed by any of '-', ',', '.', ' ', '/'
0173  *  - year: a two-digit or four-digit number
0174  *
0175  *  If the day is missing, it is assumed to be the first or last day of the month, depending on the parameter \c assumeStartDate.
0176  *  If the month is missing, it is assumed to be the first or last month of the year, depending on the parameter \c assumeStartDate.
0177  *  If the year is missing, it is assumed to be the current year.
0178  *
0179  * Examples:
0180  * ---------
0181  *  - parseDateString("Dec", true): QDate(currentYear, 12, 1)
0182  *  - parseDateString("Dec", false): QDate(currentYear, 12, 31)
0183  *  - parseDateString("2021", false): QDate(2021, 12, 31)
0184  *  - parseDateString("3. Feb. 82", true): QDate(1982, 2, 3)
0185  *  - parseDateString("3. Feb. 82", false): QDate(1982, 2, 3)
0186  *  - parseDateString("3. Feb. 12", true): QDate(2012, 2, 3)
0187  *  - parseDateString("3/2/12", true): QDate(2012, 2, 3)
0188  *  - parseDateString("03-02-12", true): QDate(2012, 2, 3)
0189  *
0190  * @param dateString a user-supplied string representing a date
0191  * @param assumeStartDate \c true to assume the first possible day of the month/year, \c false to assume the last possible day.
0192  * @return a QDate representing the parsed dateString, or an invalid QDate if the string could not be parsed.
0193  */
0194 QDate parseDateString(const QString &dateString, bool assumeStartDate);
0195 }
0196 
0197 QDebug operator<<(QDebug debug, const DB::ImageDate &d);
0198 
0199 #endif /* IMAGEDATE_H */
0200 
0201 // vi:expandtab:tabstop=4 shiftwidth=4: