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.calendar; 13 extern(C++): 14 15 import qt.config; 16 import qt.core.datetime; 17 import qt.core.locale; 18 import qt.core.metamacros; 19 import qt.core.string; 20 import qt.core.stringlist; 21 import qt.core.stringview; 22 import qt.helpers; 23 24 /* Suggested enum names for other calendars known to CLDR (v33.1) 25 26 Not yet implemented - see QCalendar::System - contributions welcome: 27 28 * Buddhist -- Thai Buddhist, to be specific 29 * Chinese 30 * Coptic 31 * Dangi -- Korean 32 * Ethiopic (Amete Mihret - epoch approx. 8 C.E.) 33 * EthiopicAmeteAlem (Amete Alem - epoch approx. 5493 B.C.E; data from 34 type="ethiopic-amete-alem", an alias for type="ethioaa") 35 * Hebrew 36 * Indian -- National 37 * Islamic -- Based on astronomical observations, not predictions, so hard to 38 implement. CLDR's data for type="islamic" apply, unless overridden, to the 39 other Islamic calendar variants, i.e. IslamicCivil, above, and the three 40 following. See QHijriCalendar, a common base to provide that data. 41 * IslamicTabular -- tabular, astronomical epoch (same as IslamicCivil, except 42 for epoch), CLDR type="islamic-tbla" 43 * Saudi -- Saudi Arabia, sighting; CLDR type="islamic-rgsa" 44 * UmmAlQura -- Umm al-Qura, Saudi Arabia, calculated; CLDR type="islamic-umalqura" 45 * Iso8601 -- as Gregorian, but treating ISO 8601 weeks as "months" 46 * Japanese -- Imperial calendar 47 * Minguo -- Republic of China, Taiwan; CLDR type="roc" 48 49 See: 50 http://www.unicode.org/repos/cldr/tags/latest/common/bcp47/calendar.xml 51 52 These can potentially be supported, as features, using CLDR's data; any 53 others shall need hand-crafted localization data; it would probably be best 54 to do that by contributing data for them to CLDR. 55 */ 56 57 58 extern(C++, class) struct QCalendarBackend; 59 60 /// Binding for C++ class [QCalendar](https://doc.qt.io/qt-6/qcalendar.html). 61 extern(C++, class) struct /+ Q_CORE_EXPORT +/ QCalendar 62 { 63 mixin(Q_GADGET); 64 public: 65 // (Extra parentheses to suppress bogus reading of min() as a macro.) 66 enum int Unspecified = int.min; 67 // Workaround for https://issues.dlang.org/show_bug.cgi?id=20701 68 extern(C++, struct) struct YearMonthDay 69 { 70 /+ YearMonthDay() = default; +/ 71 this(int y, int m = 1, int d = 1) 72 { 73 this.year = y; 74 this.month = m; 75 this.day = d; 76 } 77 78 bool isValid() const 79 { return month != Unspecified && day != Unspecified; } 80 // (The first year supported by QDate has year == Unspecified.) 81 82 int year = Unspecified; 83 int month = Unspecified; 84 int day = Unspecified; 85 } 86 // Feature (\w+)calendar uses CLDR type="\1" data, except as noted in type="..." comments below 87 enum /+ class +/ System 88 { 89 Gregorian, // CLDR: type = "gregory", alias = "gregorian" 90 /+ #ifndef QT_BOOTSTRAPPED +/ 91 Julian = 8, 92 Milankovic = 9, 93 /+ #endif // These are Roman-based, so share Gregorian's CLDR data 94 95 // Feature-controlled calendars: 96 #if QT_CONFIG(jalalicalendar) +/ // type="persian" 97 Jalali = 10, 98 /+ #endif 99 #if QT_CONFIG(islamiccivilcalendar) +/ // type="islamic-civil", uses data from type="islamic" 100 IslamicCivil = 11, 101 // tabular, civil epoch 102 // 30 year cycle, leap on 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 and 29 103 // (Other variants: 2, 5, 8, (10|11), 13, 16, 19, 21, 24, 27 and 29.) 104 /+ #endif +/ 105 106 Last = 11, // Highest number of any above 107 User = -1 108 } 109 // New entries must be added to the \enum doc in qcalendar.cpp and 110 // handled in QCalendarBackend::fromEnum() 111 /+ Q_ENUM(System) +/ 112 extern(C++, class) struct SystemId 113 { 114 private: 115 size_t id = ~size_t(0); 116 /+ friend class QCalendarBackend; +/ 117 bool isInEnum() const { return id <= size_t(QCalendar.System.Last); } 118 /+ explicit +/this(QCalendar.System e) 119 { 120 this.id = size_t(e); 121 } 122 /+ explicit +/this(size_t i) 123 { 124 this.id = i; 125 } 126 127 public: 128 @disable this(); 129 /+this() 130 { 131 this.id = UnresolvedMergeConflict!(q{~size_t(0)},q{~size_t(0)}); 132 }+/ 133 size_t index() const/+ noexcept+/ { return id; } 134 bool isValid() const/+ noexcept+/ { return (~id) != 0; } 135 } 136 137 @disable this(); 138 /+ explicit +/pragma(mangle, defaultConstructorMangling(__traits(identifier, typeof(this)))) 139 ref typeof(this) rawConstructor(); 140 static typeof(this) create() 141 { 142 typeof(this) r = typeof(this).init; 143 r.rawConstructor(); 144 return r; 145 } 146 // Gregorian, optimised 147 /+ explicit +/this(System system); 148 // ### Qt 7: remove 149 /+ explicit +/this(QLatin1String name); 150 // ### Qt 7: use QAnyStringView 151 /+ explicit +/this(QStringView name); 152 /+ explicit +/this(SystemId id); 153 154 // QCalendar is a trivially copyable value type. 155 bool isValid() const { return d_ptr !is null; } 156 157 // Date queries: 158 int daysInMonth(int month, int year = Unspecified) const; 159 int daysInYear(int year) const; 160 int monthsInYear(int year) const; 161 bool isDateValid(int year, int month, int day) const; 162 163 // Leap years: 164 bool isLeapYear(int year) const; 165 166 // Properties of the calendar: 167 bool isGregorian() const; 168 bool isLunar() const; 169 bool isLuniSolar() const; 170 bool isSolar() const; 171 bool isProleptic() const; 172 bool hasYearZero() const; 173 int maximumDaysInMonth() const; 174 int minimumDaysInMonth() const; 175 int maximumMonthsInYear() const; 176 QString name() const; 177 178 // QDate conversions: 179 QDate dateFromParts(int year, int month, int day) const; 180 QDate dateFromParts(ref const(YearMonthDay) parts) const; 181 YearMonthDay partsFromDate(QDate date) const; 182 int dayOfWeek(QDate date) const; 183 184 // Month and week-day names (as in QLocale): 185 QString monthName(ref const(QLocale) locale, int month, int year = Unspecified, 186 QLocale.FormatType format=QLocale.FormatType.LongFormat) const; 187 QString standaloneMonthName(ref const(QLocale) locale, int month, int year = Unspecified, 188 QLocale.FormatType format = QLocale.FormatType.LongFormat) const; 189 QString weekDayName(ref const(QLocale) locale, int day, 190 QLocale.FormatType format = QLocale.FormatType.LongFormat) const; 191 QString standaloneWeekDayName(ref const(QLocale) locale, int day, 192 QLocale.FormatType format=QLocale.FormatType.LongFormat) const; 193 194 // Formatting of date-times: 195 QString dateTimeToString(QStringView format, ref const(QDateTime) datetime, 196 QDate dateOnly, QTime timeOnly, 197 ref const(QLocale) locale) const; 198 199 // What's available ? 200 static QStringList availableCalendars(); 201 private: 202 // Always supplied by QCalendarBackend and expected to be a singleton 203 // Note that the calendar registry destroys all backends when it is itself 204 // destroyed. The code should check if the registry is destroyed before 205 // dereferencing this pointer. 206 const(QCalendarBackend)* d_ptr; 207 mixin(CREATE_CONVENIENCE_WRAPPERS); 208 } 209