1 /*
2  * DQt - D bindings for the Qt Toolkit
3  *
4  * GNU Lesser General Public License Usage
5  * This file may be used under the terms of the GNU Lesser
6  * General Public License version 3 as published by the Free Software
7  * Foundation and appearing in the file LICENSE.LGPL3 included in the
8  * packaging of this file. Please review the following information to
9  * ensure the GNU Lesser General Public License version 3 requirements
10  * will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
11  */
12 module qt.core.datetime;
13 extern(C++):
14 
15 import qt.config;
16 import qt.core.calendar;
17 import qt.core.global;
18 import qt.core.namespace;
19 import qt.core.string;
20 import qt.core.stringview;
21 import qt.core.timezone;
22 import qt.core.typeinfo;
23 import qt.helpers;
24 
25 /+ #if defined(Q_OS_DARWIN) || defined(Q_QDOC)
26 Q_FORWARD_DECLARE_CF_TYPE(CFDate);
27 Q_FORWARD_DECLARE_OBJC_CLASS(NSDate);
28 #endif
29 
30 
31 #if QT_CONFIG(timezone)
32 class QTimeZone;
33 #endif +/
34 
35 /// Binding for C++ class [QDate](https://doc.qt.io/qt-6/qdate.html).
36 @Q_RELOCATABLE_TYPE extern(C++, class) struct /+ Q_CORE_EXPORT +/ QDate
37 {
38 private:
39     /+ explicit +/ this(qint64 julianDay)
40     {
41         this.jd = julianDay;
42     }
43 public:
44     /+this()
45     {
46         this.jd = nullJd();
47     }+/
48     this(int y, int m, int d);
49     this(int y, int m, int d, QCalendar cal);
50 
51     bool isNull() const { return !isValid(); }
52     bool isValid() const { return jd >= minJd() && jd <= maxJd(); }
53 
54     // Gregorian-optimized:
55     int year() const;
56     int month() const;
57     int day() const;
58     int dayOfWeek() const;
59     int dayOfYear() const;
60     int daysInMonth() const;
61     int daysInYear() const;
62     int weekNumber(int* yearNum = null) const; // ISO 8601, always Gregorian
63 
64     int year(QCalendar cal) const;
65     int month(QCalendar cal) const;
66     int day(QCalendar cal) const;
67     int dayOfWeek(QCalendar cal) const;
68     int dayOfYear(QCalendar cal) const;
69     int daysInMonth(QCalendar cal) const;
70     int daysInYear(QCalendar cal) const;
71 
72     QDateTime startOfDay(/+ Qt:: +/qt.core.namespace.TimeSpec spec = /+ Qt:: +/qt.core.namespace.TimeSpec.LocalTime, int offsetSeconds = 0) const;
73     QDateTime endOfDay(/+ Qt:: +/qt.core.namespace.TimeSpec spec = /+ Qt:: +/qt.core.namespace.TimeSpec.LocalTime, int offsetSeconds = 0) const;
74 /+ #if QT_CONFIG(timezone) +/
75     QDateTime startOfDay(ref const(QTimeZone) zone) const;
76     QDateTime endOfDay(ref const(QTimeZone) zone) const;
77 /+ #endif
78 
79 #if QT_CONFIG(datestring) +/
80     QString toString(/+ Qt:: +/qt.core.namespace.DateFormat format = /+ Qt:: +/qt.core.namespace.DateFormat.TextDate) const;
81     static if(QT_STRINGVIEW_LEVEL < 2)
82     {
83         QString toString(ref const(QString) format, QCalendar cal/* = QCalendar()*/) const
84         { return toString(qToStringViewIgnoringNull(format), cal); }
85     }
86     QString toString(QStringView format, QCalendar cal/* = QCalendar()*/) const;
87 /+ #endif +/
88     bool setDate(int year, int month, int day); // Gregorian-optimized
89     bool setDate(int year, int month, int day, QCalendar cal);
90 
91     void getDate(int* year, int* month, int* day) const;
92 
93     /+ [[nodiscard]] +/ QDate addDays(qint64 days) const;
94     // Gregorian-optimized:
95     /+ [[nodiscard]] +/ QDate addMonths(int months) const;
96     /+ [[nodiscard]] +/ QDate addYears(int years) const;
97     /+ [[nodiscard]] +/ QDate addMonths(int months, QCalendar cal) const;
98     /+ [[nodiscard]] +/ QDate addYears(int years, QCalendar cal) const;
99     qint64 daysTo(QDate d) const;
100 
101     static QDate currentDate();
102 /+ #if QT_CONFIG(datestring) +/
103     static QDate fromString(QStringView string, /+ Qt:: +/qt.core.namespace.DateFormat format = /+ Qt:: +/qt.core.namespace.DateFormat.TextDate);
104     static QDate fromString(QStringView string, QStringView format, QCalendar cal/* = QCalendar()*/)
105     { auto tmp = string.toString(); return fromString(tmp, format, cal); }
106     static QDate fromString(ref const(QString) string, QStringView format, QCalendar cal/* = QCalendar()*/);
107 /+ # if QT_STRINGVIEW_LEVEL < 2 +/
108     static if(QT_STRINGVIEW_LEVEL < 2)
109     {
110         static QDate fromString(ref const(QString) string, /+ Qt:: +/qt.core.namespace.DateFormat format = /+ Qt:: +/qt.core.namespace.DateFormat.TextDate)
111         { return fromString(qToStringViewIgnoringNull(string), format); }
112         static QDate fromString(ref const(QString) string, ref const(QString) format,
113                                     QCalendar cal/* = QCalendar()*/)
114         { return fromString(string, qToStringViewIgnoringNull(format), cal); }
115     }
116 /+ # endif
117 #endif +/
118     static bool isValid(int y, int m, int d);
119     static bool isLeapYear(int year);
120 
121     pragma(inline, true) static QDate fromJulianDay(qint64 jd_)
122     { return jd_ >= minJd() && jd_ <= maxJd() ? QDate(jd_) : QDate() ; }
123     pragma(inline, true) qint64 toJulianDay() const { return jd; }
124 
125 private:
126     // using extra parentheses around min to avoid expanding it if it is a macro
127     pragma(inline, true) static qint64 nullJd() { return qint64.min; }
128     pragma(inline, true) static qint64 minJd() { return -784350574879L; }
129     pragma(inline, true) static qint64 maxJd() { return  784354017364L; }
130 
131     qint64 jd = nullJd();
132 
133     /+ friend class QDateTime; +/
134     /+ friend class QDateTimePrivate; +/
135 
136     /+ friend constexpr bool operator==(QDate lhs, QDate rhs) { return lhs.jd == rhs.jd; } +/
137     /+ friend constexpr bool operator!=(QDate lhs, QDate rhs) { return lhs.jd != rhs.jd; } +/
138     /+ friend constexpr bool operator< (QDate lhs, QDate rhs) { return lhs.jd <  rhs.jd; } +/
139     /+ friend constexpr bool operator<=(QDate lhs, QDate rhs) { return lhs.jd <= rhs.jd; } +/
140     /+ friend constexpr bool operator> (QDate lhs, QDate rhs) { return lhs.jd >  rhs.jd; } +/
141     /+ friend constexpr bool operator>=(QDate lhs, QDate rhs) { return lhs.jd >= rhs.jd; } +/
142     version(QT_NO_DATASTREAM){}else
143     {
144         /+ friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QDate); +/
145         /+ friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDate &); +/
146     }
147     mixin(CREATE_CONVENIENCE_WRAPPERS);
148 }
149 /+ Q_DECLARE_TYPEINFO(QDate, Q_RELOCATABLE_TYPE); +/
150 
151 /// Binding for C++ class [QTime](https://doc.qt.io/qt-6/qtime.html).
152 @Q_RELOCATABLE_TYPE extern(C++, class) struct /+ Q_CORE_EXPORT +/ QTime
153 {
154 private:
155     /+ explicit +/ this(int ms)
156     {
157         this.mds = ms;
158     }
159 public:
160     @disable this();
161     /+this()
162     {
163         this.mds = TimeFlag.NullTime;
164     }+/
165     this(int h, int m, int s = 0, int ms = 0);
166 
167     bool isNull() const { return mds == TimeFlag.NullTime; }
168     bool isValid() const;
169 
170     int hour() const;
171     int minute() const;
172     int second() const;
173     int msec() const;
174 /+ #if QT_CONFIG(datestring) +/
175     QString toString(/+ Qt:: +/qt.core.namespace.DateFormat f = /+ Qt:: +/qt.core.namespace.DateFormat.TextDate) const;
176     static if(QT_STRINGVIEW_LEVEL < 2)
177     {
178         QString toString(ref const(QString) format) const
179         { return toString(qToStringViewIgnoringNull(format)); }
180     }
181     QString toString(QStringView format) const;
182 /+ #endif +/
183     bool setHMS(int h, int m, int s, int ms = 0);
184 
185     /+ [[nodiscard]] +/ QTime addSecs(int secs) const;
186     int secsTo(QTime t) const;
187     /+ [[nodiscard]] +/ QTime addMSecs(int ms) const;
188     int msecsTo(QTime t) const;
189 
190     pragma(inline, true) static QTime fromMSecsSinceStartOfDay(int msecs) { return QTime(msecs); }
191     pragma(inline, true) int msecsSinceStartOfDay() const { return mds == TimeFlag.NullTime ? 0 : mds; }
192 
193     static QTime currentTime();
194 /+ #if QT_CONFIG(datestring) +/
195     static QTime fromString(QStringView string, /+ Qt:: +/qt.core.namespace.DateFormat format = /+ Qt:: +/qt.core.namespace.DateFormat.TextDate);
196     static QTime fromString(QStringView string, QStringView format)
197     { auto tmp = string.toString(); return fromString(tmp, format); }
198     static QTime fromString(ref const(QString) string, QStringView format);
199 /+ # if QT_STRINGVIEW_LEVEL < 2 +/
200     static if(QT_STRINGVIEW_LEVEL < 2)
201     {
202         static QTime fromString(ref const(QString) string, /+ Qt:: +/qt.core.namespace.DateFormat format = /+ Qt:: +/qt.core.namespace.DateFormat.TextDate)
203         { return fromString(qToStringViewIgnoringNull(string), format); }
204         static QTime fromString(ref const(QString) string, ref const(QString) format)
205         { return fromString(string, qToStringViewIgnoringNull(format)); }
206     }
207 /+ # endif
208 #endif +/
209     static bool isValid(int h, int m, int s, int ms = 0);
210 
211 private:
212     enum TimeFlag { NullTime = -1 }
213     pragma(inline, true) int ds() const { return mds == -1 ? 0 : mds; }
214     int mds = TimeFlag.NullTime;
215 
216     /+ friend constexpr bool operator==(QTime lhs, QTime rhs) { return lhs.mds == rhs.mds; } +/
217     /+ friend constexpr bool operator!=(QTime lhs, QTime rhs) { return lhs.mds != rhs.mds; } +/
218     /+ friend constexpr bool operator< (QTime lhs, QTime rhs) { return lhs.mds <  rhs.mds; } +/
219     /+ friend constexpr bool operator<=(QTime lhs, QTime rhs) { return lhs.mds <= rhs.mds; } +/
220     /+ friend constexpr bool operator> (QTime lhs, QTime rhs) { return lhs.mds >  rhs.mds; } +/
221     /+ friend constexpr bool operator>=(QTime lhs, QTime rhs) { return lhs.mds >= rhs.mds; } +/
222 
223     /+ friend class QDateTime; +/
224     /+ friend class QDateTimePrivate; +/
225     version(QT_NO_DATASTREAM){}else
226     {
227         /+ friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QTime); +/
228         /+ friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QTime &); +/
229     }
230     mixin(CREATE_CONVENIENCE_WRAPPERS);
231 }
232 /+ Q_DECLARE_TYPEINFO(QTime, Q_RELOCATABLE_TYPE); +/
233 
234 extern(C++, class) struct QDateTimePrivate;
235 
236 /// Binding for C++ class [QDateTime](https://doc.qt.io/qt-6/qdatetime.html).
237 @Q_RELOCATABLE_TYPE extern(C++, class) struct /+ Q_CORE_EXPORT +/ QDateTime
238 {
239 private:
240     struct ShortData {
241         size_t bitfieldData;
242 /+ #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN +/
243 /+        version(LittleEndian)
244         {
245             /+ quintptr status : 8; +/
246             final quintptr status() const
247             {
248                 return (bitfieldData_status >> 0) & 0xff;
249             }
250             final quintptr status(quintptr value)
251             {
252                 bitfieldData_status = (bitfieldData_status & ~0xff) | ((value & 0xff) << 0);
253                 return value;
254             }
255         }
256 /+ #endif
257 #if QT_VERSION >= QT_VERSION_CHECK(7,0,0)
258         qint64 msecs : 56;
259 #else +/
260         // note: this is only 24 bits on 32-bit systems...
261         /+ qintptr msecs : sizeof(void *) * 8 - 8; +/
262         final qintptr msecs() const
263         {
264             return (bitfieldData_msecs >> 0) & 0x1;
265         }
266         final qintptr msecs(qintptr value)
267         {
268             bitfieldData_status = (bitfieldData_status & ~0x100) | ((value & 0x1) << 8);
269             return value;
270         }
271         }
272 /+ #endif
273 
274 #if Q_BYTE_ORDER == Q_BIG_ENDIAN +/
275         version(BigEndian)
276         {
277             /+ quintptr status : 8; +/
278             final quintptr status() const
279             {
280                 return (bitfieldData_msecs >> 65) & 0xff;
281             }
282             final quintptr status(quintptr value)
283             {
284                 bitfieldData_msecs = (bitfieldData_msecs & ~0x1fe) | ((value & 0xff) << 65);
285                 return value;
286             }
287         }+/
288 /+ #endif +/
289     }
290 
291     union Data {
292         enum {
293             // To be of any use, we need at least 60 years around 1970, which
294             // is 1,893,456,000,000 ms. That requires 41 bits to store, plus
295             // the sign bit. With the status byte, the minimum size is 50 bits.
296             CanBeSmall = ShortData.sizeof * 8 > 50
297         }
298 
299         //this()/+ noexcept+/;
300         this(/+ Qt:: +/qt.core.namespace.TimeSpec);
301         /+ Data(const Data &other); +/
302         /+ Data(Data &&other); +/
303 //        ~this();
304 
305         bool isShort() const;
306         void detach();
307 
308         /+const(QDateTimePrivate)* operator ->() const;+/
309         /+QDateTimePrivate* operator ->();+/
310 
311         QDateTimePrivate* d;
312         ShortData data;
313     }
314 
315 public:
316     @disable this();
317     pragma(mangle, defaultConstructorMangling(__traits(identifier, typeof(this))))
318     ref typeof(this) rawConstructor()/+ noexcept+/;
319     static typeof(this) create()
320     {
321         typeof(this) r = typeof(this).init;
322         r.rawConstructor();
323         return r;
324     }
325 
326     this(QDate date, QTime time, /+ Qt:: +/qt.core.namespace.TimeSpec spec = /+ Qt:: +/qt.core.namespace.TimeSpec.LocalTime, int offsetSeconds = 0);
327 /+ #if QT_CONFIG(timezone) +/
328     this(QDate date, QTime time, ref const(QTimeZone) timeZone);
329 /+ #endif +/ // timezone
330     //@disable this(this);
331     //this(ref const(QDateTime) other)/+ noexcept+/;
332     /+ QDateTime(QDateTime &&other) noexcept; +/
333     ~this();
334 
335     /+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QDateTime) +/
336     /+ref QDateTime operator =(ref const(QDateTime) other)/+ noexcept+/;+/
337 
338     /+ void swap(QDateTime &other) noexcept { qSwap(d.d, other.d.d); } +/
339 
340     bool isNull() const;
341     bool isValid() const;
342 
343     QDate date() const;
344     QTime time() const;
345     /+ Qt:: +/qt.core.namespace.TimeSpec timeSpec() const;
346     int offsetFromUtc() const;
347 /+ #if QT_CONFIG(timezone) +/
348     QTimeZone timeZone() const;
349 /+ #endif +/ // timezone
350     QString timeZoneAbbreviation() const;
351     bool isDaylightTime() const;
352 
353     qint64 toMSecsSinceEpoch() const;
354     qint64 toSecsSinceEpoch() const;
355 
356     void setDate(QDate date);
357     void setTime(QTime time);
358     void setTimeSpec(/+ Qt:: +/qt.core.namespace.TimeSpec spec);
359     void setOffsetFromUtc(int offsetSeconds);
360 /+ #if QT_CONFIG(timezone) +/
361     void setTimeZone(ref const(QTimeZone) toZone);
362 /+ #endif +/ // timezone
363     void setMSecsSinceEpoch(qint64 msecs);
364     void setSecsSinceEpoch(qint64 secs);
365 
366 /+ #if QT_CONFIG(datestring) +/
367     QString toString(/+ Qt:: +/qt.core.namespace.DateFormat format = /+ Qt:: +/qt.core.namespace.DateFormat.TextDate) const;
368     static if(QT_STRINGVIEW_LEVEL < 2)
369     {
370         QString toString(ref const(QString) format, QCalendar cal/* = QCalendar()*/) const
371         { return toString(qToStringViewIgnoringNull(format), cal); }
372     }
373     QString toString(QStringView format, QCalendar cal/* = QCalendar()*/) const;
374 /+ #endif +/
375     /+ [[nodiscard]] +/ QDateTime addDays(qint64 days) const;
376     /+ [[nodiscard]] +/ QDateTime addMonths(int months) const;
377     /+ [[nodiscard]] +/ QDateTime addYears(int years) const;
378     /+ [[nodiscard]] +/ QDateTime addSecs(qint64 secs) const;
379     /+ [[nodiscard]] +/ QDateTime addMSecs(qint64 msecs) const;
380 
381     QDateTime toTimeSpec(/+ Qt:: +/qt.core.namespace.TimeSpec spec) const;
382     pragma(inline, true) QDateTime toLocalTime() const { return toTimeSpec(/+ Qt:: +/qt.core.namespace.TimeSpec.LocalTime); }
383     pragma(inline, true) QDateTime toUTC() const { return toTimeSpec(/+ Qt:: +/qt.core.namespace.TimeSpec.UTC); }
384     QDateTime toOffsetFromUtc(int offsetSeconds) const;
385 /+ #if QT_CONFIG(timezone) +/
386     QDateTime toTimeZone(ref const(QTimeZone) toZone) const;
387 /+ #endif +/ // timezone
388 
389     qint64 daysTo(ref const(QDateTime) ) const;
390     qint64 secsTo(ref const(QDateTime) ) const;
391     qint64 msecsTo(ref const(QDateTime) ) const;
392 
393     static QDateTime currentDateTime();
394     static QDateTime currentDateTimeUtc();
395 /+ #if QT_CONFIG(datestring) +/
396     static QDateTime fromString(QStringView string, /+ Qt:: +/qt.core.namespace.DateFormat format = /+ Qt:: +/qt.core.namespace.DateFormat.TextDate);
397     static QDateTime fromString(QStringView string, QStringView format,
398                                     QCalendar cal/* = QCalendar()*/)
399     { auto tmp = string.toString(); return fromString(tmp, format, cal); }
400     static QDateTime fromString(ref const(QString) string, QStringView format,
401                                     QCalendar cal/* = QCalendar()*/);
402 /+ # if QT_STRINGVIEW_LEVEL < 2 +/
403     static if(QT_STRINGVIEW_LEVEL < 2)
404     {
405         static QDateTime fromString(ref const(QString) string, /+ Qt:: +/qt.core.namespace.DateFormat format = /+ Qt:: +/qt.core.namespace.DateFormat.TextDate)
406         { return fromString(qToStringViewIgnoringNull(string), format); }
407         static QDateTime fromString(ref const(QString) string, ref const(QString) format,
408                                         QCalendar cal/* = QCalendar()*/)
409         { return fromString(string, qToStringViewIgnoringNull(format), cal); }
410     }
411 /+ # endif
412 #endif +/
413 
414     static QDateTime fromMSecsSinceEpoch(qint64 msecs, /+ Qt:: +/qt.core.namespace.TimeSpec spec = /+ Qt:: +/qt.core.namespace.TimeSpec.LocalTime,
415                                              int offsetFromUtc = 0);
416     static QDateTime fromSecsSinceEpoch(qint64 secs, /+ Qt:: +/qt.core.namespace.TimeSpec spec = /+ Qt:: +/qt.core.namespace.TimeSpec.LocalTime,
417                                             int offsetFromUtc = 0);
418 
419 /+ #if QT_CONFIG(timezone) +/
420     static QDateTime fromMSecsSinceEpoch(qint64 msecs, ref const(QTimeZone) timeZone);
421     static QDateTime fromSecsSinceEpoch(qint64 secs, ref const(QTimeZone) timeZone);
422 /+ #endif +/
423 
424     static qint64 currentMSecsSinceEpoch()/+ noexcept+/;
425     static qint64 currentSecsSinceEpoch()/+ noexcept+/;
426 
427     static if((versionIsSet!("OSX") || versionIsSet!("iOS") || versionIsSet!("TVOS") || versionIsSet!("WatchOS")))
428     {
429         /+ static QDateTime fromCFDate(CFDateRef date); +/
430         /+ CFDateRef toCFDate() const Q_DECL_CF_RETURNS_RETAINED; +/
431         /+ static QDateTime fromNSDate(const NSDate *date); +/
432         /+ NSDate *toNSDate() const Q_DECL_NS_RETURNS_AUTORELEASED; +/
433     }
434 
435     // (1<<63) ms is 292277024.6 (average Gregorian) years, counted from the start of 1970, so
436     // Last is floor(1970 + 292277024.6); no year 0, so First is floor(1970 - 1 - 292277024.6)
437     enum /+ class +/ YearRange : qint32 { First = -292275056,  Last = +292278994 }
438 
439 private:
440     bool equals(ref const(QDateTime) other) const;
441     bool precedes(ref const(QDateTime) other) const;
442     /+ friend class QDateTimePrivate; +/
443 
444     Data d;
445 
446     /+ friend bool operator==(const QDateTime &lhs, const QDateTime &rhs) { return lhs.equals(rhs); } +/
447     /+ friend bool operator!=(const QDateTime &lhs, const QDateTime &rhs) { return !(lhs == rhs); } +/
448     /+ friend bool operator<(const QDateTime &lhs, const QDateTime &rhs) { return lhs.precedes(rhs); } +/
449     /+ friend bool operator<=(const QDateTime &lhs, const QDateTime &rhs) { return !(rhs < lhs); } +/
450     /+ friend bool operator>(const QDateTime &lhs, const QDateTime &rhs) { return rhs.precedes(lhs); } +/
451     /+ friend bool operator>=(const QDateTime &lhs, const QDateTime &rhs) { return !(lhs < rhs); } +/
452 
453 /+ #ifndef QT_NO_DATASTREAM +/
454     version(QT_NO_DATASTREAM){}else
455     {
456         /+ friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &); +/
457         /+ friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &); +/
458     }
459 /+ #endif
460 
461 #if !defined(QT_NO_DEBUG_STREAM) && QT_CONFIG(datestring)
462     friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &);
463 #endif +/
464     mixin(CREATE_CONVENIENCE_WRAPPERS);
465 }
466 /+ Q_DECLARE_SHARED(QDateTime)
467 
468 #ifndef QT_NO_DATASTREAM
469 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QDate);
470 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDate &);
471 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QTime);
472 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QTime &);
473 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &);
474 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &);
475 #endif // QT_NO_DATASTREAM
476 
477 #if !defined(QT_NO_DEBUG_STREAM) && QT_CONFIG(datestring)
478 Q_CORE_EXPORT QDebug operator<<(QDebug, QDate);
479 Q_CORE_EXPORT QDebug operator<<(QDebug, QTime);
480 Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &);
481 #endif
482 
483 // QDateTime is not noexcept for now -- to be revised once
484 // timezone and calendaring support is added
485 Q_CORE_EXPORT size_t qHash(const QDateTime &key, size_t seed = 0);
486 Q_CORE_EXPORT size_t qHash(QDate key, size_t seed = 0) noexcept;
487 Q_CORE_EXPORT size_t qHash(QTime key, size_t seed = 0) noexcept; +/
488