1 | /* |
2 | Copyright (c) 2002 Carlos Moro <cfmoro@correo.uniovi.es> |
3 | Copyright (c) 2002 Hans Petter Bieker <bieker@kde.org> |
4 | Copyright 2007, 2008, 2009, 2010 John Layt <john@layt.net> |
5 | |
6 | This library is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU Library General Public |
8 | License as published by the Free Software Foundation; either |
9 | version 2 of the License, or (at your option) any later version. |
10 | |
11 | This library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Library General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Library General Public License |
17 | along with this library; see the file COPYING.LIB. If not, write to |
18 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. |
20 | */ |
21 | |
22 | #include "kcalendarsystem.h" |
23 | #include "kcalendarsystemprivate_p.h" |
24 | |
25 | #include "kdebug.h" |
26 | #include "kconfiggroup.h" |
27 | |
28 | #include <QtCore/QDateTime> |
29 | |
30 | #include "kdatetime.h" |
31 | #include "kdatetimeformatter_p.h" |
32 | #include "kdatetimeparser_p.h" |
33 | #include "kcalendarera_p.h" |
34 | #include "kcalendarsystemcoptic_p.h" |
35 | #include "kcalendarsystemethiopian_p.h" |
36 | #include "kcalendarsystemgregorian_p.h" |
37 | #include "kcalendarsystemhebrew_p.h" |
38 | #include "kcalendarsystemindiannational_p.h" |
39 | #include "kcalendarsystemislamiccivil_p.h" |
40 | #include "kcalendarsystemjalali_p.h" |
41 | #include "kcalendarsystemjapanese_p.h" |
42 | #include "kcalendarsystemjulian_p.h" |
43 | #include "kcalendarsystemminguo_p.h" |
44 | #include "kcalendarsystemqdate_p.h" |
45 | #include "kcalendarsystemthai_p.h" |
46 | |
47 | KCalendarSystem *KCalendarSystem::create(const QString &calendarType, const KLocale *locale) |
48 | { |
49 | return create(calendarSystem(calendarType), locale); |
50 | } |
51 | |
52 | KCalendarSystem *KCalendarSystem::create(const QString &calendarType, KSharedConfig::Ptr config, |
53 | const KLocale *locale) |
54 | { |
55 | return create(calendarSystem(calendarType), config, locale); |
56 | } |
57 | |
58 | QStringList KCalendarSystem::calendarSystems() |
59 | { |
60 | QStringList lst; |
61 | |
62 | lst.append(QLatin1String("coptic" )); |
63 | lst.append(QLatin1String("ethiopian" )); |
64 | lst.append(QLatin1String("gregorian" )); |
65 | lst.append(QLatin1String("gregorian-proleptic" )); |
66 | lst.append(QLatin1String("hebrew" )); |
67 | lst.append(QLatin1String("hijri" )); |
68 | lst.append(QLatin1String("indian-national" )); |
69 | lst.append(QLatin1String("jalali" )); |
70 | lst.append(QLatin1String("japanese" )); |
71 | lst.append(QLatin1String("julian" )); |
72 | lst.append(QLatin1String("minguo" )); |
73 | lst.append(QLatin1String("thai" )); |
74 | |
75 | return lst; |
76 | } |
77 | |
78 | QString KCalendarSystem::calendarLabel(const QString &calendarType) |
79 | { |
80 | if (calendarSystemsList().contains(calendarSystem(calendarType))) { |
81 | return KCalendarSystem::calendarLabel(KCalendarSystem::calendarSystem(calendarType)); |
82 | } else { |
83 | return ki18nc("@item Calendar system" , "Invalid Calendar Type" ).toString(KGlobal::locale()); |
84 | } |
85 | } |
86 | |
87 | KCalendarSystem *KCalendarSystem::create(KLocale::CalendarSystem calendarSystem, const KLocale *locale) |
88 | { |
89 | return create(calendarSystem, KSharedConfig::Ptr(), locale); |
90 | } |
91 | |
92 | KCalendarSystem *KCalendarSystem::create(KLocale::CalendarSystem calendarSystem, |
93 | KSharedConfig::Ptr config, |
94 | const KLocale *locale) |
95 | { |
96 | switch (calendarSystem) { |
97 | case KLocale::QDateCalendar: |
98 | return new KCalendarSystemQDate(config, locale); |
99 | case KLocale::CopticCalendar: |
100 | return new KCalendarSystemCoptic(config, locale); |
101 | case KLocale::EthiopianCalendar: |
102 | return new KCalendarSystemEthiopian(config, locale); |
103 | case KLocale::GregorianCalendar: |
104 | return new KCalendarSystemGregorian(config, locale); |
105 | case KLocale::HebrewCalendar: |
106 | return new KCalendarSystemHebrew(config, locale); |
107 | case KLocale::IndianNationalCalendar: |
108 | return new KCalendarSystemIndianNational(config, locale); |
109 | case KLocale::IslamicCivilCalendar: |
110 | return new KCalendarSystemIslamicCivil(config, locale); |
111 | case KLocale::JalaliCalendar: |
112 | return new KCalendarSystemJalali(config, locale); |
113 | case KLocale::JapaneseCalendar: |
114 | return new KCalendarSystemJapanese(config, locale); |
115 | case KLocale::JulianCalendar: |
116 | return new KCalendarSystemJulian(config, locale); |
117 | case KLocale::MinguoCalendar: |
118 | return new KCalendarSystemMinguo(config, locale); |
119 | case KLocale::ThaiCalendar: |
120 | return new KCalendarSystemThai(config, locale); |
121 | default: |
122 | return new KCalendarSystemQDate(config, locale); |
123 | } |
124 | } |
125 | |
126 | QList<KLocale::CalendarSystem> KCalendarSystem::calendarSystemsList() |
127 | { |
128 | QList<KLocale::CalendarSystem> list; |
129 | |
130 | list.append(KLocale::QDateCalendar); |
131 | list.append(KLocale::CopticCalendar); |
132 | list.append(KLocale::EthiopianCalendar); |
133 | list.append(KLocale::GregorianCalendar); |
134 | list.append(KLocale::HebrewCalendar); |
135 | list.append(KLocale::IslamicCivilCalendar); |
136 | list.append(KLocale::IndianNationalCalendar); |
137 | list.append(KLocale::JalaliCalendar); |
138 | list.append(KLocale::JapaneseCalendar); |
139 | list.append(KLocale::JulianCalendar); |
140 | list.append(KLocale::MinguoCalendar); |
141 | list.append(KLocale::ThaiCalendar); |
142 | |
143 | return list; |
144 | } |
145 | |
146 | QString KCalendarSystem::calendarLabel(KLocale::CalendarSystem calendarSystem, const KLocale *locale) |
147 | { |
148 | switch (calendarSystem) { |
149 | case KLocale::QDateCalendar: |
150 | return ki18nc("@item Calendar system" , "Gregorian" ).toString(locale); |
151 | case KLocale::CopticCalendar: |
152 | return ki18nc("@item Calendar system" , "Coptic" ).toString(locale); |
153 | case KLocale::EthiopianCalendar: |
154 | return ki18nc("@item Calendar system" , "Ethiopian" ).toString(locale); |
155 | case KLocale::GregorianCalendar: |
156 | return ki18nc("@item Calendar system" , "Gregorian (Proleptic)" ).toString(locale); |
157 | case KLocale::HebrewCalendar: |
158 | return ki18nc("@item Calendar system" , "Hebrew" ).toString(locale); |
159 | case KLocale::IslamicCivilCalendar: |
160 | return ki18nc("@item Calendar system" , "Islamic / Hijri (Civil)" ).toString(locale); |
161 | case KLocale::IndianNationalCalendar: |
162 | return ki18nc("@item Calendar system" , "Indian National" ).toString(locale); |
163 | case KLocale::JalaliCalendar: |
164 | return ki18nc("@item Calendar system" , "Jalali" ).toString(locale); |
165 | case KLocale::JapaneseCalendar: |
166 | return ki18nc("@item Calendar system" , "Japanese" ).toString(locale); |
167 | case KLocale::JulianCalendar: |
168 | return ki18nc("@item Calendar system" , "Julian" ).toString(locale); |
169 | case KLocale::MinguoCalendar: |
170 | return ki18nc("@item Calendar system" , "Taiwanese" ).toString(locale); |
171 | case KLocale::ThaiCalendar: |
172 | return ki18nc("@item Calendar system" , "Thai" ).toString(locale); |
173 | } |
174 | |
175 | return ki18nc("@item Calendar system" , "Invalid Calendar Type" ).toString(locale); |
176 | } |
177 | |
178 | KLocale::CalendarSystem KCalendarSystem::calendarSystemForCalendarType(const QString &calendarType ) |
179 | { |
180 | return calendarSystem( calendarType ); |
181 | } |
182 | |
183 | KLocale::CalendarSystem KCalendarSystem::calendarSystem(const QString &calendarType ) |
184 | { |
185 | if (calendarType == QLatin1String("coptic" )) { |
186 | return KLocale::CopticCalendar; |
187 | } else if (calendarType == QLatin1String("ethiopian" )) { |
188 | return KLocale::EthiopianCalendar; |
189 | } else if (calendarType == QLatin1String("gregorian" )) { |
190 | return KLocale::QDateCalendar; |
191 | } else if (calendarType == QLatin1String("gregorian-proleptic" )) { |
192 | return KLocale::GregorianCalendar; |
193 | } else if (calendarType == QLatin1String("hebrew" )) { |
194 | return KLocale::HebrewCalendar; |
195 | } else if (calendarType == QLatin1String("hijri" )) { |
196 | return KLocale::IslamicCivilCalendar; |
197 | } else if (calendarType == QLatin1String("indian-national" )) { |
198 | return KLocale::IndianNationalCalendar; |
199 | } else if (calendarType == QLatin1String("jalali" )) { |
200 | return KLocale::JalaliCalendar; |
201 | } else if (calendarType == QLatin1String("japanese" )) { |
202 | return KLocale::JapaneseCalendar; |
203 | } else if (calendarType == QLatin1String("julian" )) { |
204 | return KLocale::JulianCalendar; |
205 | } else if (calendarType == QLatin1String("minguo" )) { |
206 | return KLocale::MinguoCalendar; |
207 | } else if (calendarType == QLatin1String("thai" )) { |
208 | return KLocale::ThaiCalendar; |
209 | } else { |
210 | return KLocale::QDateCalendar; |
211 | } |
212 | } |
213 | |
214 | QString KCalendarSystem::calendarType(KLocale::CalendarSystem calendarSystem) |
215 | { |
216 | if (calendarSystem == KLocale::QDateCalendar) { |
217 | return QLatin1String("gregorian" ); |
218 | } else if (calendarSystem == KLocale::CopticCalendar) { |
219 | return QLatin1String("coptic" ); |
220 | } else if (calendarSystem == KLocale::EthiopianCalendar) { |
221 | return QLatin1String("ethiopian" ); |
222 | } else if (calendarSystem == KLocale::GregorianCalendar) { |
223 | return QLatin1String("gregorian-proleptic" ); |
224 | } else if (calendarSystem == KLocale::HebrewCalendar) { |
225 | return QLatin1String("hebrew" ); |
226 | } else if (calendarSystem == KLocale::IndianNationalCalendar) { |
227 | return QLatin1String("indian-national" ); |
228 | } else if (calendarSystem == KLocale::IslamicCivilCalendar) { |
229 | return QLatin1String("hijri" ); |
230 | } else if (calendarSystem == KLocale::JalaliCalendar) { |
231 | return QLatin1String("jalali" ); |
232 | } else if (calendarSystem == KLocale::JapaneseCalendar) { |
233 | return QLatin1String("japanese" ); |
234 | } else if (calendarSystem == KLocale::JulianCalendar) { |
235 | return QLatin1String("julian" ); |
236 | } else if (calendarSystem == KLocale::MinguoCalendar) { |
237 | return QLatin1String("minguo" ); |
238 | } else if (calendarSystem == KLocale::ThaiCalendar) { |
239 | return QLatin1String("thai" ); |
240 | } else { |
241 | return QLatin1String("gregorian" ); |
242 | } |
243 | } |
244 | |
245 | // Shared d pointer base class definitions |
246 | |
247 | KCalendarSystemPrivate::KCalendarSystemPrivate(KCalendarSystem *q_ptr) |
248 | : q(q_ptr), |
249 | m_eraList(0), |
250 | m_shortYearWindowStartYear(2000) |
251 | { |
252 | } |
253 | |
254 | KCalendarSystemPrivate::~KCalendarSystemPrivate() |
255 | { |
256 | delete m_eraList; |
257 | } |
258 | |
259 | // Dummy version using Gregorian as an example |
260 | // This method MUST be re-implemented in any new Calendar System |
261 | KLocale::CalendarSystem KCalendarSystemPrivate::calendarSystem() const |
262 | { |
263 | return KLocale::QDateCalendar; |
264 | } |
265 | |
266 | // Dummy version as an example, remember to translate (see Gregorian for example) |
267 | // Add the Era's in chronological order, from earliest to latest |
268 | // This method MUST be re-implemented in any new Calendar System |
269 | void KCalendarSystemPrivate::loadDefaultEraList() |
270 | { |
271 | addEra('-', 1, q->epoch().addDays(-1), -1, q->earliestValidDate(), QLatin1String("Before KDE" ), QLatin1String("BK" ), QLatin1String("%Ey %EC" )); |
272 | addEra('+', 1, q->epoch(), 1, q->latestValidDate(), QLatin1String("Anno KDE" ), QLatin1String("AK" ), QLatin1String("%Ey %EC" )); |
273 | } |
274 | |
275 | // Dummy version using Gregorian as an example |
276 | // This method MUST be re-implemented in any new Calendar System |
277 | int KCalendarSystemPrivate::monthsInYear(int year) const |
278 | { |
279 | Q_UNUSED(year) |
280 | return 12; |
281 | } |
282 | |
283 | // Dummy version using Gregorian as an example |
284 | // This method MUST be re-implemented in any new Calendar System |
285 | int KCalendarSystemPrivate::daysInMonth(int year, int month) const |
286 | { |
287 | if (month == 2) { |
288 | if (isLeapYear(year)) { |
289 | return 29; |
290 | } else { |
291 | return 28; |
292 | } |
293 | } |
294 | |
295 | if (month == 4 || month == 6 || month == 9 || month == 11) { |
296 | return 30; |
297 | } |
298 | |
299 | return 31; |
300 | } |
301 | |
302 | // Dummy version using Gregorian as an example |
303 | // This method MUST be re-implemented in any new Calendar System |
304 | int KCalendarSystemPrivate::daysInYear(int year) const |
305 | { |
306 | if (isLeapYear(year)) { |
307 | return 366; |
308 | } else { |
309 | return 365; |
310 | } |
311 | } |
312 | |
313 | // Dummy version using Gregorian as an example |
314 | // This method MUST be re-implemented in any new Calendar System |
315 | int KCalendarSystemPrivate::daysInWeek() const |
316 | { |
317 | return 7; |
318 | } |
319 | |
320 | // Dummy version using Gregorian as an example |
321 | // This method MUST be re-implemented in any new Calendar System |
322 | bool KCalendarSystemPrivate::isLeapYear(int year) const |
323 | { |
324 | if (year < 1) { |
325 | year = year + 1; |
326 | } |
327 | |
328 | if (year % 4 == 0) { |
329 | if (year % 100 != 0) { |
330 | return true; |
331 | } else if (year % 400 == 0) { |
332 | return true; |
333 | } |
334 | } |
335 | |
336 | return false; |
337 | } |
338 | |
339 | // Dummy version using Gregorian as an example |
340 | // This method MUST be re-implemented in any new Calendar System |
341 | bool KCalendarSystemPrivate::hasLeapMonths() const |
342 | { |
343 | return false; |
344 | } |
345 | |
346 | // Dummy version using Gregorian as an example |
347 | // This method MUST be re-implemented in any new Calendar System |
348 | bool KCalendarSystemPrivate::hasYearZero() const |
349 | { |
350 | return false; |
351 | } |
352 | |
353 | // Dummy version using Gregorian as an example |
354 | // This method MUST be re-implemented in any new Calendar System |
355 | int KCalendarSystemPrivate::maxDaysInWeek() const |
356 | { |
357 | return 7; |
358 | } |
359 | |
360 | // Dummy version using Gregorian as an example |
361 | // This method MUST be re-implemented in any new Calendar System |
362 | int KCalendarSystemPrivate::maxMonthsInYear() const |
363 | { |
364 | return 12; |
365 | } |
366 | |
367 | // Convenince, faster than calling year( ealiestValidDate() ), |
368 | // needed in fake-virtual functions so don't remove |
369 | // Dummy version using Gregorian as an example |
370 | // This method MUST be re-implemented in any new Calendar System |
371 | int KCalendarSystemPrivate::earliestValidYear() const |
372 | { |
373 | return -4712; |
374 | } |
375 | |
376 | // Convenince, faster than calling year( latestValidDate() ), |
377 | // needed in fake-virtual functions so don't remove |
378 | // Dummy version using Gregorian as an example |
379 | // This method MUST be re-implemented in any new Calendar System |
380 | int KCalendarSystemPrivate::latestValidYear() const |
381 | { |
382 | return 9999; |
383 | } |
384 | |
385 | // Dummy version |
386 | // This method MUST be re-implemented in any new Calendar System |
387 | QString KCalendarSystemPrivate::monthName(int month, int year, KLocale::DateTimeComponentFormat format, bool possessive) const |
388 | { |
389 | Q_UNUSED(month); |
390 | Q_UNUSED(year); |
391 | Q_UNUSED(format); |
392 | Q_UNUSED(possessive); |
393 | return QString(); |
394 | } |
395 | |
396 | // Dummy version |
397 | // This method MUST be re-implemented in any new Calendar System |
398 | QString KCalendarSystemPrivate::weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const |
399 | { |
400 | Q_UNUSED(weekDay); |
401 | Q_UNUSED(format); |
402 | return QString(); |
403 | } |
404 | |
405 | // Reimplement if special maths handling required, e.g. Hebrew. |
406 | int KCalendarSystemPrivate::week(const QDate &date, KLocale::WeekNumberSystem weekNumberSystem, int *yearNum) const |
407 | { |
408 | int y, m, d; |
409 | q->julianDayToDate(date.toJulianDay(), y, m, d); |
410 | |
411 | switch (weekNumberSystem) { |
412 | case KLocale::IsoWeekNumber: |
413 | return isoWeekNumber(date, yearNum); |
414 | case KLocale::FirstFullWeek: |
415 | return regularWeekNumber(date, locale()->weekStartDay(), 0, yearNum); |
416 | case KLocale::FirstPartialWeek: |
417 | return regularWeekNumber(date, locale()->weekStartDay(), 1, yearNum); |
418 | case KLocale::SimpleWeek: |
419 | return simpleWeekNumber(date, yearNum); |
420 | case KLocale::DefaultWeekNumber: |
421 | default: |
422 | return week(date, locale()->weekNumberSystem(), yearNum); |
423 | } |
424 | } |
425 | |
426 | // Reimplement if special maths handling required, e.g. Hebrew. |
427 | int KCalendarSystemPrivate::isoWeekNumber(const QDate &date, int *yearNum) const |
428 | { |
429 | int y, m, d; |
430 | q->julianDayToDate(date.toJulianDay(), y, m, d); |
431 | |
432 | QDate firstDayWeek1, lastDay; |
433 | int week; |
434 | int weekDay1, dayOfWeek1InYear; |
435 | |
436 | // let's guess 1st day of 1st week |
437 | firstDayWeek1 = firstDayOfYear(y); |
438 | weekDay1 = dayOfWeek(firstDayWeek1); |
439 | |
440 | // iso 8601: week 1 is the first containing thursday and week starts on monday |
441 | if (weekDay1 > 4 /*Thursday*/) { |
442 | firstDayWeek1 = q->addDays(firstDayWeek1 , daysInWeek() - weekDay1 + 1); // next monday |
443 | } |
444 | |
445 | dayOfWeek1InYear = dayOfYear(firstDayWeek1); |
446 | |
447 | // our date in prev year's week |
448 | if (dayOfYear(date) < dayOfWeek1InYear) { |
449 | if (yearNum) { |
450 | *yearNum = addYears(y, - 1); |
451 | } |
452 | return isoWeeksInYear(addYears(y, - 1)); |
453 | } |
454 | |
455 | // let's check if its last week belongs to next year |
456 | lastDay = lastDayOfYear(y); |
457 | |
458 | // if our date is in last week && 1st week in next year has thursday |
459 | if ((dayOfYear(date) >= daysInYear(y) - dayOfWeek(lastDay) + 1) |
460 | && dayOfWeek(lastDay) < 4) { |
461 | if (yearNum) { |
462 | * yearNum = addYears(y, 1); |
463 | } |
464 | week = 1; |
465 | } else { |
466 | // To calculate properly the number of weeks from day a to x let's make a day 1 of week |
467 | if (weekDay1 < 5) { |
468 | firstDayWeek1 = q->addDays(firstDayWeek1, -(weekDay1 - 1)); |
469 | } |
470 | |
471 | if (yearNum) { |
472 | * yearNum = y; |
473 | } |
474 | |
475 | week = firstDayWeek1.daysTo(date) / daysInWeek() + 1; |
476 | } |
477 | |
478 | return week; |
479 | } |
480 | |
481 | // Reimplement if special maths handling required, e.g. Hebrew. |
482 | int KCalendarSystemPrivate::regularWeekNumber(const QDate &date, int weekStartDay, int firstWeekNumber, int *weekYear) const |
483 | { |
484 | int y, m, d; |
485 | q->julianDayToDate(date.toJulianDay(), y, m, d); |
486 | |
487 | int firstWeekDayOffset = (dayOfWeek(date) - weekStartDay + daysInWeek()) % daysInWeek(); |
488 | int dayInYear = date.toJulianDay() - firstDayOfYear(y).toJulianDay(); // 0 indexed |
489 | int week = ((dayInYear - firstWeekDayOffset + daysInWeek()) / daysInWeek()); |
490 | |
491 | if (dayOfWeek(firstDayOfYear(y)) != weekStartDay) { |
492 | week = week + firstWeekNumber; |
493 | } |
494 | |
495 | if (week < 1) { |
496 | y = y - 1; |
497 | week = regularWeeksInYear(y, weekStartDay, firstWeekNumber); |
498 | } |
499 | |
500 | if (weekYear) { |
501 | *weekYear = y; |
502 | } |
503 | |
504 | return week; |
505 | } |
506 | |
507 | // Reimplement if special maths handling required, e.g. Hebrew. |
508 | int KCalendarSystemPrivate::simpleWeekNumber(const QDate &date, int *yearNum) const |
509 | { |
510 | int y, m, d; |
511 | q->julianDayToDate(date.toJulianDay(), y, m, d); |
512 | if (yearNum) { |
513 | *yearNum = y; |
514 | } |
515 | return ((date.toJulianDay() - firstDayOfYear(y).toJulianDay()) / daysInWeek()) + 1; |
516 | } |
517 | |
518 | // Reimplement if special maths handling required, e.g. Hebrew. |
519 | int KCalendarSystemPrivate::weeksInYear(int year, KLocale::WeekNumberSystem weekNumberSystem) const |
520 | { |
521 | switch (weekNumberSystem) { |
522 | case KLocale::IsoWeekNumber: |
523 | return isoWeeksInYear(year); |
524 | case KLocale::FirstFullWeek: |
525 | return regularWeeksInYear(year, locale()->weekStartDay(), 0); |
526 | case KLocale::FirstPartialWeek: |
527 | return regularWeeksInYear(year, locale()->weekStartDay(), 1); |
528 | case KLocale::SimpleWeek: |
529 | return simpleWeeksInYear(year); |
530 | case KLocale::DefaultWeekNumber: |
531 | default: |
532 | return weeksInYear(year, locale()->weekNumberSystem()); |
533 | } |
534 | } |
535 | |
536 | // Reimplement if special maths handling required, e.g. Hebrew. |
537 | int KCalendarSystemPrivate::isoWeeksInYear(int year) const |
538 | { |
539 | QDate lastDayOfThisYear = lastDayOfYear(year); |
540 | |
541 | int weekYear = year; |
542 | int lastWeekInThisYear = isoWeekNumber(lastDayOfThisYear, &weekYear); |
543 | |
544 | // If error, or the last day of the year is in the first week of next year use the week before |
545 | if (lastWeekInThisYear < 1 || weekYear != year) { |
546 | lastWeekInThisYear = isoWeekNumber(q->addDays(lastDayOfThisYear, -7), &weekYear); |
547 | } |
548 | |
549 | return lastWeekInThisYear; |
550 | } |
551 | |
552 | // Reimplement if special maths handling required, e.g. Hebrew. |
553 | int KCalendarSystemPrivate::regularWeeksInYear(int year, int weekStartDay, int firstWeekNumber) const |
554 | { |
555 | return regularWeekNumber(lastDayOfYear(year), weekStartDay, firstWeekNumber, 0); |
556 | } |
557 | |
558 | // Reimplement if special maths handling required, e.g. Hebrew. |
559 | int KCalendarSystemPrivate::simpleWeeksInYear(int year) const |
560 | { |
561 | return simpleWeekNumber(lastDayOfYear(year), 0); |
562 | } |
563 | |
564 | // Reimplement if special maths handling required, e.g. Hebrew. |
565 | // Works for calendars with constant number of months, or where leap month is last month of year |
566 | // Will not work for Hebrew or others where leap month is inserted in middle of year |
567 | void KCalendarSystemPrivate::dateDifference(const QDate &fromDate, const QDate &toDate, |
568 | int *yearsDiff, int *monthsDiff, int *daysDiff, int *direction) const |
569 | { |
570 | // This could be optimised a little but is left in full as it's easier to understand |
571 | int dy = 0; |
572 | int dm = 0; |
573 | int dd = 0; |
574 | int dir = 1; |
575 | |
576 | if (toDate < fromDate) { |
577 | dateDifference(toDate, fromDate, &dy, &dm, &dd, 0); |
578 | dir = -1; |
579 | } else if (toDate > fromDate) { |
580 | |
581 | int fromYear = q->year(fromDate); |
582 | int toYear = q->year(toDate); |
583 | int fromMonth = q->month(fromDate); |
584 | int toMonth = q->month(toDate); |
585 | int fromDay = q->day(fromDate); |
586 | int toDay = q->day(toDate); |
587 | |
588 | int monthsInPrevYear = monthsInYear(addYears(toYear, -1)); |
589 | int daysInPrevMonth = q->daysInMonth(q->addMonths(toDate, -1)); |
590 | int daysInFromMonth = daysInMonth(fromYear, fromMonth); |
591 | int daysInToMonth = daysInMonth(toYear, toMonth); |
592 | |
593 | // Calculate years difference |
594 | if (toYear == fromYear) { |
595 | dy = 0; |
596 | } else if (toMonth > fromMonth) { |
597 | dy = differenceYearNumbers(fromYear, toYear); |
598 | } else if (toMonth < fromMonth) { |
599 | dy = differenceYearNumbers(fromYear, toYear) - 1; |
600 | } else { // toMonth == fromMonth |
601 | // Allow for last day of month to last day of month and leap days |
602 | // e.g. 2000-02-29 to 2001-02-28 is 1 year not 0 years |
603 | if ((toDay >= fromDay) || (fromDay == daysInFromMonth && toDay == daysInToMonth)) { |
604 | dy = differenceYearNumbers(fromYear, toYear); |
605 | } else { |
606 | dy = differenceYearNumbers(fromYear, toYear) - 1; |
607 | } |
608 | } |
609 | |
610 | // Calculate months and days difference |
611 | if (toDay >= fromDay) { |
612 | dm = (monthsInPrevYear + toMonth - fromMonth) % monthsInPrevYear; |
613 | dd = toDay - fromDay; |
614 | } else { // toDay < fromDay |
615 | // Allow for last day of month to last day of month and leap days |
616 | // e.g. 2010-03-31 to 2010-04-30 is 1 month |
617 | // 2000-02-29 to 2001-02-28 is 1 year |
618 | // 2000-02-29 to 2001-03-01 is 1 year 1 day |
619 | int prevMonth = q->month(q->addMonths(toDate, -1)); |
620 | if (fromDay == daysInFromMonth && toDay == daysInToMonth) { |
621 | dm = (monthsInPrevYear + toMonth - fromMonth) % monthsInPrevYear; |
622 | dd = 0; |
623 | } else if (prevMonth == fromMonth && daysInPrevMonth < daysInFromMonth) { |
624 | // Special case where fromDate = leap day and toDate in month following but non-leap year |
625 | // e.g. 2000-02-29 to 2001-03-01 needs to use 29 to calculate day number not 28 |
626 | dm = (monthsInPrevYear + toMonth - fromMonth - 1) % monthsInPrevYear; |
627 | dd = (daysInFromMonth + toDay - fromDay) % daysInFromMonth; |
628 | } else { |
629 | dm = (monthsInPrevYear + toMonth - fromMonth - 1) % monthsInPrevYear; |
630 | dd = (daysInPrevMonth + toDay - fromDay) % daysInPrevMonth; |
631 | } |
632 | } |
633 | |
634 | } |
635 | |
636 | // Only return values if we have a valid pointer |
637 | if (yearsDiff) { |
638 | *yearsDiff = dy; |
639 | } |
640 | if (monthsDiff) { |
641 | *monthsDiff = dm; |
642 | } |
643 | if (daysDiff) { |
644 | *daysDiff = dd; |
645 | } |
646 | if (direction) { |
647 | *direction = dir; |
648 | } |
649 | } |
650 | |
651 | // Reimplement if special maths handling required, e.g. Hebrew |
652 | // Allows for calendars with leap months at end of year but not during year |
653 | int KCalendarSystemPrivate::yearsDifference(const QDate &fromDate, const QDate &toDate) const |
654 | { |
655 | // This could be optimised a little but is left in full as it's easier to understand |
656 | // Alternatively could just call dateDifference(), but this is slightly more efficient |
657 | |
658 | if (toDate < fromDate) { |
659 | return 0 - yearsDifference(toDate, fromDate); |
660 | } |
661 | |
662 | if (toDate == fromDate) { |
663 | return 0; |
664 | } |
665 | |
666 | int fromYear = q->year(fromDate); |
667 | int toYear = q->year(toDate); |
668 | |
669 | if (toYear == fromYear) { |
670 | return 0; |
671 | } |
672 | |
673 | int fromMonth = q->month(fromDate); |
674 | int toMonth = q->month(toDate); |
675 | |
676 | if (toMonth > fromMonth) { |
677 | return differenceYearNumbers(fromYear, toYear); |
678 | } |
679 | |
680 | if (toMonth < fromMonth) { |
681 | return differenceYearNumbers(fromYear, toYear) - 1; |
682 | } |
683 | |
684 | // toMonth == fromMonth |
685 | int fromDay = q->day(fromDate); |
686 | int toDay = q->day(toDate); |
687 | |
688 | // Adjust for month numbers in from and to year |
689 | // Allow for last day of month to last day of month and leap days |
690 | // e.g. 2000-02-29 to 2001-02-28 is 1 year not 0 years |
691 | if ((toDay >= fromDay) || |
692 | (fromDay == daysInMonth(fromYear, fromMonth) && |
693 | toDay == daysInMonth(toYear, toMonth))) { |
694 | return differenceYearNumbers(fromYear, toYear); |
695 | } else { |
696 | return differenceYearNumbers(fromYear, toYear) - 1; |
697 | } |
698 | |
699 | } |
700 | |
701 | // Reimplement if special maths handling required, e.g. maybe Hebrew? |
702 | // Allows for calendars with leap months |
703 | int KCalendarSystemPrivate::monthsDifference(const QDate &fromDate, const QDate &toDate) const |
704 | { |
705 | if (toDate < fromDate) { |
706 | return 0 - monthsDifference(toDate, fromDate); |
707 | } |
708 | |
709 | if (toDate == fromDate) { |
710 | return 0; |
711 | } |
712 | |
713 | int fromYear = q->year(fromDate); |
714 | int toYear = q->year(toDate); |
715 | int fromMonth = q->month(fromDate); |
716 | int toMonth = q->month(toDate); |
717 | int fromDay = q->day(fromDate); |
718 | int toDay = q->day(toDate); |
719 | |
720 | int monthsInPreceedingYears; |
721 | |
722 | // Calculate number of months in full years preceding toYear |
723 | if (toYear == fromYear) { |
724 | monthsInPreceedingYears = 0; |
725 | } else if (hasLeapMonths()) { |
726 | monthsInPreceedingYears = 0; |
727 | for (int y = fromYear; y < toYear; y = addYears(y, 1)) { |
728 | monthsInPreceedingYears = monthsInPreceedingYears + monthsInYear(y); |
729 | } |
730 | } else { |
731 | monthsInPreceedingYears = differenceYearNumbers(fromYear, toYear) * monthsInYear(toYear); |
732 | } |
733 | |
734 | // Adjust for months in from and to year |
735 | // Allow for last day of month to last day of month and leap days |
736 | // e.g. 2010-03-31 to 2010-04-30 is 1 month not 0 months |
737 | // also 2000-02-29 to 2001-02-28 is 12 months not 11 months |
738 | if ((toDay >= fromDay) || |
739 | (fromDay == daysInMonth(fromYear, fromMonth) && |
740 | toDay == daysInMonth(toYear, toMonth))) { |
741 | return monthsInPreceedingYears + toMonth - fromMonth; |
742 | } else { |
743 | return monthsInPreceedingYears + toMonth - fromMonth - 1; |
744 | } |
745 | } |
746 | |
747 | // Reimplement if special string to integer handling required, e.g. Hebrew. |
748 | // Peel a number off the front of a string which may have other trailing chars after the number |
749 | // Stop either at either maxLength, eos, or first non-digit char |
750 | int KCalendarSystemPrivate::integerFromString(const QString &string, int maxLength, int &readLength) const |
751 | { |
752 | int value = -1; |
753 | int position = 0; |
754 | readLength = 0; |
755 | bool ok = false; |
756 | |
757 | if (maxLength < 0) { |
758 | maxLength = string.length(); |
759 | } |
760 | |
761 | while (position < string.length() && |
762 | position < maxLength && |
763 | string.at(position).isDigit()) { |
764 | position++; |
765 | } |
766 | |
767 | if (position > 0) { |
768 | value = string.left(position).toInt(&ok); |
769 | if (ok) { |
770 | readLength = position; |
771 | } else { |
772 | value = -1; |
773 | } |
774 | } |
775 | |
776 | return value; |
777 | } |
778 | |
779 | // Reimplement if special integer to string handling required, e.g. Hebrew. |
780 | // Utility to convert an integer into the correct display string form |
781 | QString KCalendarSystemPrivate::stringFromInteger(int number, int padWidth, QChar padChar) const |
782 | { |
783 | return stringFromInteger(number, padWidth, padChar, q->locale()->dateTimeDigitSet()); |
784 | } |
785 | |
786 | // Reimplement if special integer to string handling required, e.g. Hebrew. |
787 | // Utility to convert an integer into the correct display string form |
788 | QString KCalendarSystemPrivate::stringFromInteger(int number, int padWidth, QChar padChar, KLocale::DigitSet digitSet) const |
789 | { |
790 | if (padChar == QLatin1Char('\0') || padWidth == 0) { |
791 | return q->locale()->convertDigits(QString::number(number), digitSet); |
792 | } else { |
793 | return q->locale()->convertDigits(QString::number(number).rightJustified(padWidth, padChar), digitSet); |
794 | } |
795 | } |
796 | |
797 | // Allows us to set dates outside publically valid range, USE WITH CARE!!!! |
798 | bool KCalendarSystemPrivate::setAnyDate(QDate &date, int year, int month, int day) const |
799 | { |
800 | int jd; |
801 | q->dateToJulianDay(year, month, day, jd); |
802 | date = QDate::fromJulianDay(jd); |
803 | return true; |
804 | } |
805 | |
806 | // Utility to correctly add years to a year number because some systems such as |
807 | // Julian and Gregorian calendars don't have a year 0 |
808 | int KCalendarSystemPrivate::addYears(int originalYear, int addYears) const |
809 | { |
810 | int newYear = originalYear + addYears; |
811 | |
812 | if (!hasYearZero()) { |
813 | if (originalYear > 0 && newYear <= 0) { |
814 | newYear = newYear - 1; |
815 | } else if (originalYear < 0 && newYear >= 0) { |
816 | newYear = newYear + 1; |
817 | } |
818 | } |
819 | |
820 | return newYear; |
821 | } |
822 | |
823 | // Utility to correctly return number of years between two year numbers because some systems such as |
824 | // Julian and Gregorian calendars don't have a year 0 |
825 | int KCalendarSystemPrivate::differenceYearNumbers(int fromYear, int toYear) const |
826 | { |
827 | int dy = toYear - fromYear; |
828 | |
829 | if (!hasYearZero()) { |
830 | if (toYear > 0 && fromYear < 0) { |
831 | dy = dy - 1; |
832 | } else if (toYear < 0 && fromYear > 0) { |
833 | dy = dy + 1; |
834 | } |
835 | } |
836 | |
837 | return dy; |
838 | } |
839 | |
840 | QDate KCalendarSystemPrivate::invalidDate() const |
841 | { |
842 | //Is QDate's way of saying is invalid |
843 | return QDate(); |
844 | } |
845 | |
846 | QString KCalendarSystemPrivate::simpleDateString(const QString &str) const |
847 | { |
848 | QString newStr; |
849 | for (int i = 0; i < str.length(); i++) { |
850 | if (str.at(i).isLetterOrNumber()) { |
851 | newStr.append(str.at(i)); |
852 | } else { |
853 | newStr.append(QLatin1Char(' ')); |
854 | } |
855 | } |
856 | |
857 | return newStr.simplified(); |
858 | } |
859 | |
860 | int KCalendarSystemPrivate::dayOfYear(const QDate &date) const |
861 | { |
862 | int y, m, d, jdFirstDayOfYear; |
863 | q->julianDayToDate(date.toJulianDay(), y, m, d); |
864 | q->dateToJulianDay(y, 1, 1, jdFirstDayOfYear); |
865 | //Take the jd of the given date, and subtract the jd of the first day of that year |
866 | return (date.toJulianDay() - jdFirstDayOfYear + 1); |
867 | } |
868 | |
869 | int KCalendarSystemPrivate::dayOfWeek(const QDate &date) const |
870 | { |
871 | // Makes assumption that Julian Day 0 was day 1 of week |
872 | // This is true for Julian/Gregorian calendar with jd 0 being Monday |
873 | // We add 1 for ISO compliant numbering for 7 day week |
874 | // Assumes we've never skipped weekdays |
875 | return ((date.toJulianDay() % daysInWeek()) + 1); |
876 | } |
877 | |
878 | QDate KCalendarSystemPrivate::firstDayOfYear(int year) const |
879 | { |
880 | int jd; |
881 | q->dateToJulianDay(year, 1, 1, jd); |
882 | return QDate::fromJulianDay(jd); |
883 | } |
884 | |
885 | QDate KCalendarSystemPrivate::lastDayOfYear(int year) const |
886 | { |
887 | int jd; |
888 | q->dateToJulianDay(year, 1, 1, jd); |
889 | jd = jd + daysInYear(year) - 1; |
890 | return QDate::fromJulianDay(jd); |
891 | } |
892 | |
893 | QDate KCalendarSystemPrivate::firstDayOfMonth(int year, int month) const |
894 | { |
895 | int jd; |
896 | q->dateToJulianDay(year, month, 1, jd); |
897 | return QDate::fromJulianDay(jd); |
898 | } |
899 | |
900 | QDate KCalendarSystemPrivate::lastDayOfMonth(int year, int month) const |
901 | { |
902 | int jd; |
903 | q->dateToJulianDay(year, month, 1, jd); |
904 | jd = jd + daysInMonth(year, month) - 1; |
905 | return QDate::fromJulianDay(jd); |
906 | } |
907 | |
908 | const KLocale * KCalendarSystemPrivate::locale() const |
909 | { |
910 | if (m_locale) { |
911 | return m_locale; |
912 | } else { |
913 | return KGlobal::locale(); |
914 | } |
915 | } |
916 | |
917 | QList<KCalendarEra> *KCalendarSystemPrivate::eraList() const |
918 | { |
919 | return m_eraList; |
920 | } |
921 | |
922 | KCalendarEra KCalendarSystemPrivate::era(const QDate &eraDate) const |
923 | { |
924 | for (int i = m_eraList->count() - 1; i >= 0; --i) { |
925 | if (m_eraList->at(i).isInEra(eraDate)) { |
926 | return m_eraList->at(i); |
927 | } |
928 | } |
929 | return KCalendarEra(); |
930 | } |
931 | |
932 | KCalendarEra KCalendarSystemPrivate::era(const QString &eraName, int yearInEra) const |
933 | { |
934 | Q_UNUSED(yearInEra) |
935 | |
936 | for (int i = m_eraList->count() - 1; i >= 0; --i) { |
937 | KCalendarEra era = m_eraList->at(i); |
938 | if (era.name(KLocale::LongName).toLower() == eraName.toLower() || |
939 | era.name(KLocale::ShortName).toLower() == eraName.toLower()) { |
940 | return era; |
941 | } |
942 | } |
943 | return KCalendarEra(); |
944 | } |
945 | |
946 | void KCalendarSystemPrivate::loadEraList(const KConfigGroup & cg) |
947 | { |
948 | delete m_eraList; |
949 | m_eraList = new QList<KCalendarEra>; |
950 | QString eraKey = QString::fromLatin1("Era1" ); |
951 | int i = 1; |
952 | while (cg.hasKey(eraKey)) { |
953 | QString eraEntry = cg.readEntry(eraKey, QString()); |
954 | if (!eraEntry.isEmpty()) { |
955 | // Based on LC_TIME, but different! |
956 | // Includes long and short names, uses ISO fomat dates |
957 | // e.g. +:1:0001-01-01:9999-12-31:Anno Domini:AD:%EC %Ey |
958 | QChar direction = eraEntry.section(QLatin1Char(':'), 0, 0).at(0); |
959 | QDate startDate, endDate; |
960 | int startYear; |
961 | QString buffer = eraEntry.section(QLatin1Char(':'), 2, 2); |
962 | if (buffer.isEmpty()) { |
963 | if (direction == QLatin1Char('-')) { |
964 | startDate = q->latestValidDate(); |
965 | } else { |
966 | startDate = q->earliestValidDate(); |
967 | } |
968 | } else { |
969 | startDate = q->readDate(buffer, KLocale::IsoFormat); |
970 | } |
971 | if (q->isValid(startDate)) { |
972 | startYear = q->year(startDate); |
973 | } else { |
974 | startYear = eraEntry.section(QLatin1Char(':'), 1, 1).toInt(); //Use offset |
975 | } |
976 | |
977 | buffer = eraEntry.section(QLatin1Char(':'), 3, 3); |
978 | if (buffer.isEmpty()) { |
979 | if (direction == QLatin1Char('-')) { |
980 | endDate = q->earliestValidDate(); |
981 | } else { |
982 | endDate = q->latestValidDate(); |
983 | } |
984 | } else { |
985 | endDate = q->readDate(buffer, KLocale::IsoFormat); |
986 | } |
987 | addEra(direction.toLatin1(), eraEntry.section(QLatin1Char(':'), 1, 1).toInt(), |
988 | startDate, startYear, endDate, eraEntry.section(QLatin1Char(':'), 4, 4), |
989 | eraEntry.section(QLatin1Char(':'), 5, 5), eraEntry.section(QLatin1Char(':'), 6)); |
990 | } |
991 | ++i; |
992 | eraKey = QString::fromLatin1("Era%1" ).arg(i); |
993 | } |
994 | |
995 | if (m_eraList->isEmpty()) { |
996 | loadDefaultEraList(); |
997 | } |
998 | } |
999 | |
1000 | void KCalendarSystemPrivate::addEra(char direction, int offset, |
1001 | const QDate &startDate, int startYear, const QDate &endDate, |
1002 | const QString &name, const QString &shortName, |
1003 | const QString &format) |
1004 | { |
1005 | KCalendarEra newEra; |
1006 | |
1007 | newEra.m_sequence = m_eraList->count() + 1; |
1008 | if (direction == '-') { |
1009 | newEra.m_direction = -1; |
1010 | } else { |
1011 | newEra.m_direction = 1; |
1012 | } |
1013 | newEra.m_offset = offset; |
1014 | newEra.m_startDate = startDate; |
1015 | newEra.m_startYear = startYear; |
1016 | newEra.m_endDate = endDate; |
1017 | newEra.m_longName = name; |
1018 | newEra.m_shortName = shortName; |
1019 | newEra.m_format = format; |
1020 | |
1021 | m_eraList->append(newEra); |
1022 | } |
1023 | |
1024 | int KCalendarSystemPrivate::shortYearWindowStartYear() const |
1025 | { |
1026 | return m_shortYearWindowStartYear; |
1027 | } |
1028 | |
1029 | int KCalendarSystemPrivate::applyShortYearWindow(int inputYear) const |
1030 | { |
1031 | if (inputYear >= 0 && inputYear <= 99) { |
1032 | int shortStartYear = m_shortYearWindowStartYear % 100; |
1033 | int yearOffset = m_shortYearWindowStartYear - shortStartYear; |
1034 | if (inputYear >= shortStartYear) { |
1035 | return inputYear + yearOffset; |
1036 | } else { |
1037 | return inputYear + yearOffset + 100; |
1038 | } |
1039 | } else { |
1040 | return inputYear; |
1041 | } |
1042 | } |
1043 | |
1044 | void KCalendarSystemPrivate::loadShortYearWindowStartYear(const KConfigGroup & cg) |
1045 | { |
1046 | // Default to 2000 for backwards compatibility |
1047 | // as that's the old readDate() default value |
1048 | int startYear = 2000; |
1049 | if (cg.exists()) { |
1050 | startYear = cg.readEntry("ShortYearWindowStartYear" , 2000); |
1051 | } |
1052 | m_shortYearWindowStartYear = startYear; |
1053 | } |
1054 | |
1055 | KSharedConfig::Ptr KCalendarSystemPrivate::config() |
1056 | { |
1057 | if (m_config == KSharedConfig::Ptr()) { |
1058 | return KGlobal::config(); |
1059 | } else { |
1060 | return m_config; |
1061 | } |
1062 | } |
1063 | |
1064 | void KCalendarSystemPrivate::loadConfig(const QString & calendarType) |
1065 | { |
1066 | KConfigGroup localeGroup(config(), QString::fromLatin1("Locale" )); |
1067 | KConfigGroup calendarGroup = localeGroup.group(QString::fromLatin1("KCalendarSystem %1" ).arg(calendarType)); |
1068 | loadEraList(calendarGroup); |
1069 | loadShortYearWindowStartYear(calendarGroup); |
1070 | } |
1071 | |
1072 | |
1073 | KCalendarSystem::KCalendarSystem(const KLocale *locale) |
1074 | : d_ptr(new KCalendarSystemPrivate(this)) |
1075 | { |
1076 | d_ptr->m_config = KSharedConfig::Ptr(); |
1077 | d_ptr->m_locale = locale; |
1078 | } |
1079 | |
1080 | KCalendarSystem::KCalendarSystem(const KSharedConfig::Ptr config, const KLocale *locale) |
1081 | : d_ptr(new KCalendarSystemPrivate(this)) |
1082 | { |
1083 | d_ptr->m_config = config; |
1084 | d_ptr->m_locale = locale; |
1085 | } |
1086 | |
1087 | KCalendarSystem::KCalendarSystem(KCalendarSystemPrivate &dd, const KSharedConfig::Ptr config, const KLocale *locale) |
1088 | : d_ptr(&dd) |
1089 | { |
1090 | d_ptr->m_config = config; |
1091 | d_ptr->m_locale = locale; |
1092 | } |
1093 | |
1094 | KCalendarSystem::~KCalendarSystem() |
1095 | { |
1096 | delete d_ptr; |
1097 | } |
1098 | |
1099 | // NOT VIRTUAL - If override needed use shared-d |
1100 | KLocale::CalendarSystem KCalendarSystem::calendarSystem() const |
1101 | { |
1102 | Q_D(const KCalendarSystem); |
1103 | |
1104 | return d->calendarSystem(); |
1105 | } |
1106 | |
1107 | // NOT VIRTUAL - If override needed use shared-d |
1108 | QString KCalendarSystem::calendarLabel() const |
1109 | { |
1110 | return KCalendarSystem::calendarLabel(calendarSystem()); |
1111 | } |
1112 | |
1113 | // Dummy version using Gregorian as an example |
1114 | // This method MUST be re-implemented in any new Calendar System |
1115 | QDate KCalendarSystem::epoch() const |
1116 | { |
1117 | return QDate::fromJulianDay(38); |
1118 | } |
1119 | |
1120 | QDate KCalendarSystem::earliestValidDate() const |
1121 | { |
1122 | return epoch(); |
1123 | } |
1124 | |
1125 | // Dummy version using Gregorian as an example |
1126 | // This method MUST be re-implemented in any new Calendar System |
1127 | QDate KCalendarSystem::latestValidDate() const |
1128 | { |
1129 | // Default to Gregorian 9999-12-31 |
1130 | return QDate::fromJulianDay(5373484); |
1131 | } |
1132 | |
1133 | bool KCalendarSystem::isValid(int year, int month, int day) const |
1134 | { |
1135 | Q_D(const KCalendarSystem); |
1136 | |
1137 | if (year < d->earliestValidYear() || year > d->latestValidYear() || |
1138 | (!d->hasYearZero() && year == 0)) { |
1139 | return false; |
1140 | } |
1141 | |
1142 | if (month < 1 || month > d->monthsInYear(year)) { |
1143 | return false; |
1144 | } |
1145 | |
1146 | if (day < 1 || day > d->daysInMonth(year, month)) { |
1147 | return false; |
1148 | } |
1149 | |
1150 | return true; |
1151 | } |
1152 | |
1153 | // NOT VIRTUAL - If override needed use shared-d |
1154 | bool KCalendarSystem::isValid(int year, int dayOfYear) const |
1155 | { |
1156 | Q_D(const KCalendarSystem); |
1157 | |
1158 | return (isValid(year, 1, 1) && dayOfYear > 0 && dayOfYear <= d->daysInYear(year)); |
1159 | } |
1160 | |
1161 | // NOT VIRTUAL - If override needed use shared-d |
1162 | bool KCalendarSystem::isValid(const QString &eraName, int yearInEra, int month, int day) const |
1163 | { |
1164 | Q_D(const KCalendarSystem); |
1165 | |
1166 | KCalendarEra era = d->era(eraName, yearInEra); |
1167 | return (era.isValid() && isValid(era.year(yearInEra), month, day)); |
1168 | } |
1169 | |
1170 | // NOT VIRTUAL - If override needed use shared-d |
1171 | bool KCalendarSystem::isValidIsoWeekDate(int year, int isoWeekNumber, int dayOfIsoWeek) const |
1172 | { |
1173 | Q_D(const KCalendarSystem); |
1174 | |
1175 | //Tests Year value in standard YMD isValid() |
1176 | if (!isValid(year, 1, 1)) { |
1177 | return false; |
1178 | } |
1179 | |
1180 | //Test Week Number falls in valid range for this year |
1181 | int weeksInThisYear = weeksInYear(year); |
1182 | if (isoWeekNumber < 1 || isoWeekNumber > weeksInThisYear) { |
1183 | return false; |
1184 | } |
1185 | |
1186 | //Test Day of Week Number falls in valid range |
1187 | if (dayOfIsoWeek < 1 || dayOfIsoWeek > d->daysInWeek()) { |
1188 | return false; |
1189 | } |
1190 | |
1191 | //If not in earliest or latest years then all OK |
1192 | //Otherwise need to check don't fall into previous or next year that would be invalid |
1193 | if (year == d->earliestValidYear() && isoWeekNumber == 1) { |
1194 | //If firstDayOfYear falls on or before Thursday then firstDayOfYear falls in week 1 this |
1195 | //year and if wanted dayOfIsoWeek falls before firstDayOfYear then falls in previous year |
1196 | //and so in invalid year |
1197 | int dowFirstDay = dayOfWeek(d->firstDayOfYear(year)); |
1198 | if (dowFirstDay <= 4 && dayOfIsoWeek < dowFirstDay) { |
1199 | return false; |
1200 | } |
1201 | } else if (year == d->latestValidYear() && isoWeekNumber == weeksInThisYear) { |
1202 | //If lastDayOfYear falls on or after Thursday then lastDayOfYear falls in last week this |
1203 | //year and if wanted dayOfIsoWeek falls after lastDayOfYear then falls in next year |
1204 | //and so in invalid year |
1205 | int dowLastDay = dayOfWeek(d->lastDayOfYear(year)); |
1206 | if (dowLastDay >= 4 && dayOfIsoWeek > dowLastDay) { |
1207 | return false; |
1208 | } |
1209 | } |
1210 | |
1211 | return true; |
1212 | } |
1213 | |
1214 | bool KCalendarSystem::isValid(const QDate &date) const |
1215 | { |
1216 | if (date.isNull() || date < earliestValidDate() || date > latestValidDate()) { |
1217 | return false; |
1218 | } |
1219 | return true; |
1220 | } |
1221 | |
1222 | bool KCalendarSystem::setDate(QDate &date, int year, int month, int day) const |
1223 | { |
1224 | Q_D(const KCalendarSystem); |
1225 | |
1226 | date = d->invalidDate(); |
1227 | |
1228 | if (isValid(year, month, day)) { |
1229 | int jd; |
1230 | dateToJulianDay(year, month, day, jd); |
1231 | QDate calcDate = QDate::fromJulianDay(jd); |
1232 | |
1233 | if (isValid(calcDate)) { |
1234 | date = calcDate; |
1235 | return true; |
1236 | } |
1237 | } |
1238 | |
1239 | return false; |
1240 | } |
1241 | |
1242 | // NOT VIRTUAL - If override needed use shared-d |
1243 | bool KCalendarSystem::setDate(QDate &date, int year, int dayOfYear) const |
1244 | { |
1245 | Q_D(const KCalendarSystem); |
1246 | |
1247 | date = d->invalidDate(); |
1248 | |
1249 | if (isValid(year, dayOfYear)) { |
1250 | int jd; |
1251 | dateToJulianDay(year, 1, 1, jd); |
1252 | QDate calcDate = QDate::fromJulianDay(jd + dayOfYear - 1); |
1253 | if (isValid(calcDate)) { |
1254 | date = calcDate; |
1255 | return true; |
1256 | } |
1257 | } |
1258 | |
1259 | return false; |
1260 | } |
1261 | |
1262 | // NOT VIRTUAL - If override needed use shared-d |
1263 | bool KCalendarSystem::setDate(QDate &date, QString eraName, int yearInEra, int month, int day) const |
1264 | { |
1265 | Q_D(const KCalendarSystem); |
1266 | |
1267 | KCalendarEra era = d->era(eraName, yearInEra); |
1268 | return (era.isValid() && setDate(date, era.year(yearInEra), month, day)); |
1269 | } |
1270 | |
1271 | // NOT VIRTUAL - If override needed use shared-d |
1272 | bool KCalendarSystem::setDateIsoWeek(QDate &date, int year, int isoWeekNumber, int dayOfIsoWeek) const |
1273 | { |
1274 | Q_D(const KCalendarSystem); |
1275 | |
1276 | date = d->invalidDate(); |
1277 | |
1278 | if (isValidIsoWeekDate(year, isoWeekNumber, dayOfIsoWeek)) { |
1279 | |
1280 | QDate calcDate = d->firstDayOfYear(year); |
1281 | int dowFirstDayOfYear = dayOfWeek(calcDate); |
1282 | |
1283 | int daysToAdd = (d->daysInWeek() * (isoWeekNumber - 1)) + dayOfIsoWeek; |
1284 | |
1285 | if (dowFirstDayOfYear <= 4) { |
1286 | calcDate = calcDate.addDays(daysToAdd - dowFirstDayOfYear); |
1287 | } else { |
1288 | calcDate = calcDate.addDays(daysInWeek(calcDate) + daysToAdd - dowFirstDayOfYear); |
1289 | } |
1290 | |
1291 | if (isValid(calcDate)) { |
1292 | date = calcDate; |
1293 | return true; |
1294 | } |
1295 | } |
1296 | |
1297 | return false; |
1298 | } |
1299 | |
1300 | // Deprecated |
1301 | bool KCalendarSystem::setYMD(QDate &date, int year, int month, int day) const |
1302 | { |
1303 | return setDate(date, year, month, day); |
1304 | } |
1305 | |
1306 | // NOT VIRTUAL - If override needed use shared-d |
1307 | void KCalendarSystem::getDate(const QDate date, int *year, int *month, int *day) const |
1308 | { |
1309 | int y, m, d; |
1310 | |
1311 | if (isValid(date)) { |
1312 | julianDayToDate(date.toJulianDay(), y, m, d); |
1313 | } else { |
1314 | y = 0; // How do you denote invalid year when we support -ve years? |
1315 | m = 0; |
1316 | d = 0; |
1317 | } |
1318 | |
1319 | if (year) { |
1320 | *year = y; |
1321 | } |
1322 | if (month) { |
1323 | *month = m; |
1324 | } |
1325 | if (day) { |
1326 | *day = d; |
1327 | } |
1328 | |
1329 | } |
1330 | |
1331 | int KCalendarSystem::year(const QDate &date) const |
1332 | { |
1333 | if (isValid(date)) { |
1334 | int year, month, day; |
1335 | |
1336 | julianDayToDate(date.toJulianDay(), year, month, day); |
1337 | |
1338 | return year; |
1339 | } |
1340 | |
1341 | return 0; // How do you denote invalid year when we support -ve years? |
1342 | } |
1343 | |
1344 | int KCalendarSystem::month(const QDate &date) const |
1345 | { |
1346 | if (isValid(date)) { |
1347 | int year, month, day; |
1348 | |
1349 | julianDayToDate(date.toJulianDay(), year, month, day); |
1350 | |
1351 | return month; |
1352 | } |
1353 | |
1354 | return 0; |
1355 | } |
1356 | |
1357 | int KCalendarSystem::day(const QDate &date) const |
1358 | { |
1359 | if (isValid(date)) { |
1360 | int year, month, day; |
1361 | |
1362 | julianDayToDate(date.toJulianDay(), year, month, day); |
1363 | |
1364 | return day; |
1365 | } |
1366 | |
1367 | return 0; |
1368 | } |
1369 | |
1370 | // NOT VIRTUAL - If override needed use shared-d |
1371 | QString KCalendarSystem::eraName(const QDate &date, StringFormat format) const |
1372 | { |
1373 | Q_D(const KCalendarSystem); |
1374 | |
1375 | if (isValid(date)) { |
1376 | if (format == LongFormat) { |
1377 | return d->era(date).name(KLocale::LongName); |
1378 | } else { |
1379 | return d->era(date).name(KLocale::ShortName); |
1380 | } |
1381 | } |
1382 | |
1383 | return QString(); |
1384 | } |
1385 | |
1386 | // NOT VIRTUAL - If override needed use shared-d |
1387 | QString KCalendarSystem::eraYear(const QDate &date, StringFormat format) const |
1388 | { |
1389 | Q_UNUSED(format) |
1390 | Q_D(const KCalendarSystem); |
1391 | |
1392 | if (isValid(date)) { |
1393 | return formatDate(date, d->era(date).format()); |
1394 | } |
1395 | |
1396 | return QString(); |
1397 | } |
1398 | |
1399 | // NOT VIRTUAL - If override needed use shared-d |
1400 | int KCalendarSystem::yearInEra(const QDate &date) const |
1401 | { |
1402 | Q_D(const KCalendarSystem); |
1403 | |
1404 | if (isValid(date)) { |
1405 | return d->era(date).yearInEra(year(date)); |
1406 | } |
1407 | |
1408 | return -1; |
1409 | } |
1410 | |
1411 | // NOT VIRTUAL - If override needed use shared-d |
1412 | QList<KCalendarEra> *KCalendarSystem::eraList() const |
1413 | { |
1414 | Q_D(const KCalendarSystem); |
1415 | |
1416 | return d->eraList(); |
1417 | } |
1418 | |
1419 | // NOT VIRTUAL - If override needed use shared-d |
1420 | KCalendarEra KCalendarSystem::era(const QDate &eraDate) const |
1421 | { |
1422 | Q_D(const KCalendarSystem); |
1423 | |
1424 | return d->era(eraDate); |
1425 | } |
1426 | |
1427 | // NOT VIRTUAL - If override needed use shared-d |
1428 | KCalendarEra KCalendarSystem::era(const QString &eraName, int yearInEra) const |
1429 | { |
1430 | Q_D(const KCalendarSystem); |
1431 | |
1432 | return d->era(eraName, yearInEra); |
1433 | } |
1434 | |
1435 | QDate KCalendarSystem::addYears(const QDate &date, int numYears) const |
1436 | { |
1437 | Q_D(const KCalendarSystem); |
1438 | |
1439 | if (isValid(date)) { |
1440 | |
1441 | int originalYear, originalMonth, originalDay; |
1442 | julianDayToDate(date.toJulianDay(), originalYear, originalMonth, originalDay); |
1443 | |
1444 | int newYear = d->addYears(originalYear, numYears); |
1445 | int newMonth = originalMonth; |
1446 | int newDay = originalDay; |
1447 | |
1448 | //Adjust day number if new month has fewer days than old month |
1449 | int daysInNewMonth = d->daysInMonth(newYear, newMonth); |
1450 | if (daysInNewMonth < originalDay) { |
1451 | newDay = daysInNewMonth; |
1452 | } |
1453 | |
1454 | QDate newDate; |
1455 | setDate(newDate, newYear, newMonth, newDay); |
1456 | return newDate; |
1457 | |
1458 | } |
1459 | |
1460 | return d->invalidDate(); |
1461 | } |
1462 | |
1463 | QDate KCalendarSystem::addMonths(const QDate &date, int numMonths) const |
1464 | { |
1465 | Q_D(const KCalendarSystem); |
1466 | |
1467 | if (isValid(date)) { |
1468 | |
1469 | int originalYear, originalMonth, originalDay; |
1470 | julianDayToDate(date.toJulianDay(), originalYear, originalMonth, originalDay); |
1471 | |
1472 | int monthsInOriginalYear = d->monthsInYear(originalYear); |
1473 | |
1474 | int newYear = d->addYears(originalYear, (originalMonth + numMonths) / monthsInOriginalYear); |
1475 | int newMonth = (originalMonth + numMonths) % monthsInOriginalYear; |
1476 | int newDay = originalDay; |
1477 | |
1478 | if (newMonth == 0) { |
1479 | newYear = d->addYears(newYear, - 1); |
1480 | newMonth = monthsInOriginalYear; |
1481 | } |
1482 | if (newMonth < 0) { |
1483 | newYear = d->addYears(newYear, - 1); |
1484 | newMonth = newMonth + monthsInOriginalYear; |
1485 | } |
1486 | |
1487 | //Adjust day number if new month has fewer days than old month |
1488 | int daysInNewMonth = d->daysInMonth(newYear, newMonth); |
1489 | if (daysInNewMonth < originalDay) { |
1490 | newDay = daysInNewMonth; |
1491 | } |
1492 | |
1493 | QDate newDate; |
1494 | setDate(newDate, newYear, newMonth, newDay); |
1495 | return newDate; |
1496 | |
1497 | } |
1498 | |
1499 | return d->invalidDate(); |
1500 | } |
1501 | |
1502 | QDate KCalendarSystem::addDays(const QDate &date, int numDays) const |
1503 | { |
1504 | Q_D(const KCalendarSystem); |
1505 | |
1506 | // QDate only holds a uint and has no boundary checking in addDays(), so we need to check |
1507 | if (isValid(date) && (long) date.toJulianDay() + (long) numDays > 0) { |
1508 | // QDate adds straight to jd |
1509 | QDate temp = date.addDays(numDays); |
1510 | if (isValid(temp)) { |
1511 | return temp; |
1512 | } |
1513 | } |
1514 | |
1515 | return d->invalidDate(); |
1516 | } |
1517 | |
1518 | // NOT VIRTUAL - Uses shared-d instead |
1519 | void KCalendarSystem::dateDifference(const QDate &fromDate, const QDate &toDate, |
1520 | int *yearsDiff, int *monthsDiff, int *daysDiff, int *direction) const |
1521 | { |
1522 | Q_D(const KCalendarSystem); |
1523 | |
1524 | if (isValid(fromDate) && isValid(toDate)) { |
1525 | d->dateDifference(fromDate, toDate, yearsDiff, monthsDiff, daysDiff, direction); |
1526 | } |
1527 | } |
1528 | |
1529 | // NOT VIRTUAL - Uses shared-d instead |
1530 | int KCalendarSystem::yearsDifference(const QDate &fromDate, const QDate &toDate) const |
1531 | { |
1532 | Q_D(const KCalendarSystem); |
1533 | |
1534 | if (isValid(fromDate) && isValid(toDate)) { |
1535 | return d->yearsDifference(fromDate, toDate); |
1536 | } |
1537 | |
1538 | return 0; |
1539 | } |
1540 | |
1541 | // NOT VIRTUAL - Uses shared-d instead |
1542 | int KCalendarSystem::monthsDifference(const QDate &fromDate, const QDate &toDate) const |
1543 | { |
1544 | Q_D(const KCalendarSystem); |
1545 | |
1546 | if (isValid(fromDate) && isValid(toDate)) { |
1547 | return d->monthsDifference(fromDate, toDate); |
1548 | } |
1549 | |
1550 | return 0; |
1551 | } |
1552 | |
1553 | // NOT VIRTUAL - Uses shared-d instead |
1554 | int KCalendarSystem::daysDifference(const QDate &fromDate, const QDate &toDate) const |
1555 | { |
1556 | if (isValid(fromDate) && isValid(toDate)) { |
1557 | return toDate.toJulianDay() - fromDate.toJulianDay(); |
1558 | } |
1559 | |
1560 | return 0; |
1561 | } |
1562 | |
1563 | int KCalendarSystem::monthsInYear(const QDate &date) const |
1564 | { |
1565 | Q_D(const KCalendarSystem); |
1566 | |
1567 | if (isValid(date)) { |
1568 | return d->monthsInYear(year(date)); |
1569 | } |
1570 | |
1571 | return -1; |
1572 | } |
1573 | |
1574 | // NOT VIRTUAL - Uses shared-d instead |
1575 | int KCalendarSystem::monthsInYear(int year) const |
1576 | { |
1577 | Q_D(const KCalendarSystem); |
1578 | |
1579 | if (isValid(year, 1, 1)) { |
1580 | return d->monthsInYear(year); |
1581 | } |
1582 | |
1583 | return -1; |
1584 | } |
1585 | |
1586 | int KCalendarSystem::weeksInYear(const QDate &date) const |
1587 | { |
1588 | return weeksInYear(date, KLocale::DefaultWeekNumber); |
1589 | } |
1590 | |
1591 | int KCalendarSystem::weeksInYear(int year) const |
1592 | { |
1593 | return weeksInYear(year, KLocale::DefaultWeekNumber); |
1594 | } |
1595 | |
1596 | // NOT VIRTUAL - Uses shared-d instead |
1597 | int KCalendarSystem::weeksInYear(const QDate &date, KLocale::WeekNumberSystem weekNumberSystem) const |
1598 | { |
1599 | Q_D(const KCalendarSystem); |
1600 | |
1601 | if (isValid(date)) { |
1602 | return d->weeksInYear(year(date), weekNumberSystem); |
1603 | } |
1604 | |
1605 | return -1; |
1606 | } |
1607 | |
1608 | // NOT VIRTUAL - Uses shared-d instead |
1609 | int KCalendarSystem::weeksInYear(int year, KLocale::WeekNumberSystem weekNumberSystem) const |
1610 | { |
1611 | Q_D(const KCalendarSystem); |
1612 | |
1613 | if (isValid(year, 1, 1)) { |
1614 | return d->weeksInYear(year, weekNumberSystem); |
1615 | } |
1616 | |
1617 | return -1; |
1618 | } |
1619 | |
1620 | int KCalendarSystem::daysInYear(const QDate &date) const |
1621 | { |
1622 | Q_D(const KCalendarSystem); |
1623 | |
1624 | if (isValid(date)) { |
1625 | return d->daysInYear(year(date)); |
1626 | } |
1627 | |
1628 | return -1; |
1629 | } |
1630 | |
1631 | // NOT VIRTUAL - Uses shared-d instead |
1632 | int KCalendarSystem::daysInYear(int year) const |
1633 | { |
1634 | Q_D(const KCalendarSystem); |
1635 | |
1636 | if (isValid(year, 1, 1)) { |
1637 | return d->daysInYear(year); |
1638 | } |
1639 | |
1640 | return -1; |
1641 | } |
1642 | |
1643 | int KCalendarSystem::daysInMonth(const QDate &date) const |
1644 | { |
1645 | Q_D(const KCalendarSystem); |
1646 | |
1647 | if (isValid(date)) { |
1648 | int year, month; |
1649 | getDate(date, &year, &month, 0); |
1650 | return d->daysInMonth(year, month); |
1651 | } |
1652 | |
1653 | return -1; |
1654 | } |
1655 | |
1656 | // NOT VIRTUAL - Uses shared-d instead |
1657 | int KCalendarSystem::daysInMonth(int year, int month) const |
1658 | { |
1659 | Q_D(const KCalendarSystem); |
1660 | |
1661 | if (isValid(year, 1, 1)) { |
1662 | return d->daysInMonth(year, month); |
1663 | } |
1664 | |
1665 | return -1; |
1666 | } |
1667 | |
1668 | int KCalendarSystem::daysInWeek(const QDate &date) const |
1669 | { |
1670 | Q_UNUSED(date) |
1671 | Q_D(const KCalendarSystem); |
1672 | return d->daysInWeek(); |
1673 | } |
1674 | |
1675 | int KCalendarSystem::dayOfYear(const QDate &date) const |
1676 | { |
1677 | Q_D(const KCalendarSystem); |
1678 | |
1679 | if (isValid(date)) { |
1680 | return d->dayOfYear(date); |
1681 | } |
1682 | |
1683 | return -1; |
1684 | } |
1685 | |
1686 | int KCalendarSystem::dayOfWeek(const QDate &date) const |
1687 | { |
1688 | Q_D(const KCalendarSystem); |
1689 | |
1690 | if (isValid(date)) { |
1691 | return d->dayOfWeek(date); |
1692 | } |
1693 | |
1694 | return -1; |
1695 | } |
1696 | |
1697 | int KCalendarSystem::weekNumber(const QDate &date, int *yearNum) const |
1698 | { |
1699 | return week(date, KLocale::IsoWeekNumber, yearNum); |
1700 | } |
1701 | |
1702 | // NOT VIRTUAL - Uses shared-d instead |
1703 | int KCalendarSystem::week(const QDate &date, int *yearNum) const |
1704 | { |
1705 | return week(date, KLocale::DefaultWeekNumber, yearNum); |
1706 | } |
1707 | |
1708 | // NOT VIRTUAL - Uses shared-d instead |
1709 | int KCalendarSystem::week(const QDate &date, KLocale::WeekNumberSystem weekNumberSystem, int *yearNum) const |
1710 | { |
1711 | Q_D(const KCalendarSystem); |
1712 | |
1713 | if (isValid(date)) { |
1714 | return d->week(date, weekNumberSystem, yearNum); |
1715 | } |
1716 | |
1717 | return -1; |
1718 | } |
1719 | |
1720 | bool KCalendarSystem::isLeapYear(int year) const |
1721 | { |
1722 | Q_D(const KCalendarSystem); |
1723 | |
1724 | if (isValid(year, 1, 1)) { |
1725 | return d->isLeapYear(year); |
1726 | } |
1727 | |
1728 | return false; |
1729 | } |
1730 | |
1731 | bool KCalendarSystem::isLeapYear(const QDate &date) const |
1732 | { |
1733 | Q_D(const KCalendarSystem); |
1734 | |
1735 | if (isValid(date)) { |
1736 | return d->isLeapYear(year(date)); |
1737 | } |
1738 | |
1739 | return false; |
1740 | } |
1741 | |
1742 | // NOT VIRTUAL - If override needed use shared-d |
1743 | QDate KCalendarSystem::firstDayOfYear(int year) const |
1744 | { |
1745 | Q_D(const KCalendarSystem); |
1746 | |
1747 | if (isValid(year, 1, 1)) { |
1748 | return d->firstDayOfYear(year); |
1749 | } |
1750 | |
1751 | return QDate(); |
1752 | } |
1753 | |
1754 | // NOT VIRTUAL - If override needed use shared-d |
1755 | QDate KCalendarSystem::lastDayOfYear(int year) const |
1756 | { |
1757 | Q_D(const KCalendarSystem); |
1758 | |
1759 | if (isValid(year, 1, 1)) { |
1760 | return d->lastDayOfYear(year); |
1761 | } |
1762 | |
1763 | return QDate(); |
1764 | } |
1765 | |
1766 | // NOT VIRTUAL - If override needed use shared-d |
1767 | QDate KCalendarSystem::firstDayOfYear(const QDate &date) const |
1768 | { |
1769 | Q_D(const KCalendarSystem); |
1770 | |
1771 | if (isValid(date)) { |
1772 | return d->firstDayOfYear(year(date)); |
1773 | } |
1774 | |
1775 | return QDate(); |
1776 | } |
1777 | |
1778 | // NOT VIRTUAL - If override needed use shared-d |
1779 | QDate KCalendarSystem::lastDayOfYear(const QDate &date) const |
1780 | { |
1781 | Q_D(const KCalendarSystem); |
1782 | |
1783 | if (isValid(date)) { |
1784 | return d->lastDayOfYear(year(date)); |
1785 | } |
1786 | |
1787 | return QDate(); |
1788 | } |
1789 | |
1790 | // NOT VIRTUAL - If override needed use shared-d |
1791 | QDate KCalendarSystem::firstDayOfMonth(int year, int month) const |
1792 | { |
1793 | Q_D(const KCalendarSystem); |
1794 | |
1795 | if (isValid(year, month, 1)) { |
1796 | return d->firstDayOfMonth(year, month); |
1797 | } |
1798 | |
1799 | return QDate(); |
1800 | } |
1801 | |
1802 | // NOT VIRTUAL - If override needed use shared-d |
1803 | QDate KCalendarSystem::lastDayOfMonth(int year, int month) const |
1804 | { |
1805 | Q_D(const KCalendarSystem); |
1806 | |
1807 | if (isValid(year, month, 1)) { |
1808 | return d->lastDayOfMonth(year, month); |
1809 | } |
1810 | |
1811 | return QDate(); |
1812 | } |
1813 | |
1814 | // NOT VIRTUAL - If override needed use shared-d |
1815 | QDate KCalendarSystem::firstDayOfMonth(const QDate &date) const |
1816 | { |
1817 | Q_D(const KCalendarSystem); |
1818 | |
1819 | if (isValid(date)) { |
1820 | int year, month; |
1821 | getDate(date, &year, &month, 0); |
1822 | return d->firstDayOfMonth(year, month); |
1823 | } |
1824 | |
1825 | return QDate(); |
1826 | } |
1827 | |
1828 | // NOT VIRTUAL - If override needed use shared-d |
1829 | QDate KCalendarSystem::lastDayOfMonth(const QDate &date) const |
1830 | { |
1831 | Q_D(const KCalendarSystem); |
1832 | |
1833 | if (isValid(date)) { |
1834 | int year, month; |
1835 | getDate(date, &year, &month, 0); |
1836 | return d->lastDayOfMonth(year, month); |
1837 | } |
1838 | |
1839 | return QDate(); |
1840 | } |
1841 | |
1842 | QString KCalendarSystem::monthName(int month, int year, KCalendarSystem::MonthNameFormat format) const |
1843 | { |
1844 | Q_D(const KCalendarSystem); |
1845 | |
1846 | if (!isValid(year, month, 1)) { |
1847 | return QString(); |
1848 | } |
1849 | |
1850 | if (format == KCalendarSystem::NarrowName) { |
1851 | return d->monthName(month, year, KLocale::NarrowName, false); |
1852 | } |
1853 | |
1854 | if (format == KCalendarSystem::ShortNamePossessive) { |
1855 | return d->monthName(month, year, KLocale::ShortName, true); |
1856 | } |
1857 | |
1858 | if (format == KCalendarSystem::ShortName) { |
1859 | return d->monthName(month, year, KLocale::ShortName, false); |
1860 | } |
1861 | |
1862 | if (format == KCalendarSystem::LongNamePossessive) { |
1863 | return d->monthName(month, year, KLocale::LongName, true); |
1864 | } |
1865 | |
1866 | // KCalendarSystem::LongName or any other |
1867 | return d->monthName(month, year, KLocale::LongName, false); |
1868 | } |
1869 | |
1870 | QString KCalendarSystem::monthName(const QDate &date, MonthNameFormat format) const |
1871 | { |
1872 | if (isValid(date)) { |
1873 | int year, month; |
1874 | getDate(date, &year, &month, 0); |
1875 | return monthName(month, year, format); |
1876 | } |
1877 | |
1878 | return QString(); |
1879 | } |
1880 | |
1881 | QString KCalendarSystem::weekDayName(int weekDay, KCalendarSystem::WeekDayNameFormat format) const |
1882 | { |
1883 | Q_D(const KCalendarSystem); |
1884 | |
1885 | if (weekDay < 1 || weekDay > d->daysInWeek()) { |
1886 | return QString(); |
1887 | } |
1888 | |
1889 | if (format == KCalendarSystem::NarrowDayName) { |
1890 | return d->weekDayName(weekDay, KLocale::NarrowName); |
1891 | } |
1892 | |
1893 | if (format == KCalendarSystem::ShortDayName) { |
1894 | return d->weekDayName(weekDay, KLocale::ShortName); |
1895 | } |
1896 | |
1897 | return d->weekDayName(weekDay, KLocale::LongName); |
1898 | } |
1899 | |
1900 | QString KCalendarSystem::weekDayName(const QDate &date, WeekDayNameFormat format) const |
1901 | { |
1902 | if (isValid(date)) { |
1903 | return weekDayName(dayOfWeek(date), format); |
1904 | } |
1905 | |
1906 | return QString(); |
1907 | } |
1908 | |
1909 | QString KCalendarSystem::yearString(const QDate &date, StringFormat format) const |
1910 | { |
1911 | if (format == ShortFormat) { |
1912 | return formatDate(date, KLocale::Year, KLocale::ShortNumber); |
1913 | } else { |
1914 | return formatDate(date, KLocale::Year, KLocale::LongNumber); |
1915 | } |
1916 | } |
1917 | |
1918 | QString KCalendarSystem::monthString(const QDate &date, StringFormat format) const |
1919 | { |
1920 | if (format == ShortFormat) { |
1921 | return formatDate(date, KLocale::Month, KLocale::ShortNumber); |
1922 | } else { |
1923 | return formatDate(date, KLocale::Month, KLocale::LongNumber); |
1924 | } |
1925 | } |
1926 | |
1927 | QString KCalendarSystem::dayString(const QDate &date, StringFormat format) const |
1928 | { |
1929 | if (format == ShortFormat) { |
1930 | return formatDate(date, KLocale::Day, KLocale::ShortNumber); |
1931 | } else { |
1932 | return formatDate(date, KLocale::Day, KLocale::LongNumber); |
1933 | } |
1934 | } |
1935 | |
1936 | // NOT VIRTUAL - If override needed use shared-d |
1937 | QString KCalendarSystem::yearInEraString(const QDate &date, StringFormat format) const |
1938 | { |
1939 | if (format == ShortFormat) { |
1940 | return formatDate(date, KLocale::YearInEra, KLocale::ShortNumber); |
1941 | } else { |
1942 | return formatDate(date, KLocale::YearInEra, KLocale::LongNumber); |
1943 | } |
1944 | } |
1945 | |
1946 | // NOT VIRTUAL - If override needed use shared-d |
1947 | QString KCalendarSystem::dayOfYearString(const QDate &date, StringFormat format) const |
1948 | { |
1949 | if (format == ShortFormat) { |
1950 | return formatDate(date, KLocale::DayOfYear, KLocale::ShortNumber); |
1951 | } else { |
1952 | return formatDate(date, KLocale::DayOfYear, KLocale::LongNumber); |
1953 | } |
1954 | } |
1955 | |
1956 | // NOT VIRTUAL - If override needed use shared-d |
1957 | QString KCalendarSystem::dayOfWeekString(const QDate &date) const |
1958 | { |
1959 | return formatDate(date, KLocale::DayOfWeek, KLocale::ShortNumber); |
1960 | } |
1961 | |
1962 | // NOT VIRTUAL - If override needed use shared-d |
1963 | QString KCalendarSystem::weekNumberString(const QDate &date, StringFormat format) const |
1964 | { |
1965 | if (format == ShortFormat) { |
1966 | return formatDate(date, KLocale::Week, KLocale::ShortNumber); |
1967 | } else { |
1968 | return formatDate(date, KLocale::Week, KLocale::LongNumber); |
1969 | } |
1970 | } |
1971 | |
1972 | // NOT VIRTUAL - If override needed use shared-d |
1973 | QString KCalendarSystem::monthsInYearString(const QDate &date, StringFormat format) const |
1974 | { |
1975 | if (format == ShortFormat) { |
1976 | return formatDate(date, KLocale::MonthsInYear, KLocale::ShortNumber); |
1977 | } else { |
1978 | return formatDate(date, KLocale::MonthsInYear, KLocale::LongNumber); |
1979 | } |
1980 | } |
1981 | |
1982 | // NOT VIRTUAL - If override needed use shared-d |
1983 | QString KCalendarSystem::weeksInYearString(const QDate &date, StringFormat format) const |
1984 | { |
1985 | if (format == ShortFormat) { |
1986 | return formatDate(date, KLocale::WeeksInYear, KLocale::ShortNumber); |
1987 | } else { |
1988 | return formatDate(date, KLocale::WeeksInYear, KLocale::LongNumber); |
1989 | } |
1990 | } |
1991 | |
1992 | // NOT VIRTUAL - If override needed use shared-d |
1993 | QString KCalendarSystem::daysInYearString(const QDate &date, StringFormat format) const |
1994 | { |
1995 | if (format == ShortFormat) { |
1996 | return formatDate(date, KLocale::DaysInYear, KLocale::ShortNumber); |
1997 | } else { |
1998 | return formatDate(date, KLocale::DaysInYear, KLocale::LongNumber); |
1999 | } |
2000 | } |
2001 | |
2002 | // NOT VIRTUAL - If override needed use shared-d |
2003 | QString KCalendarSystem::daysInMonthString(const QDate &date, StringFormat format) const |
2004 | { |
2005 | if (format == ShortFormat) { |
2006 | return formatDate(date, KLocale::DaysInMonth, KLocale::ShortNumber); |
2007 | } else { |
2008 | return formatDate(date, KLocale::DaysInMonth, KLocale::LongNumber); |
2009 | } |
2010 | } |
2011 | |
2012 | // NOT VIRTUAL - If override needed use shared-d |
2013 | QString KCalendarSystem::daysInWeekString(const QDate &date) const |
2014 | { |
2015 | return formatDate(date, KLocale::DaysInWeek, KLocale::ShortNumber); |
2016 | } |
2017 | |
2018 | int KCalendarSystem::yearStringToInteger(const QString &yearString, int &readLength) const |
2019 | { |
2020 | Q_D(const KCalendarSystem); |
2021 | |
2022 | QString minus = i18nc("Negative symbol as used for year numbers, e.g. -5 = 5 BC" , "-" ); |
2023 | if (yearString.startsWith(minus)) { |
2024 | int value = d->integerFromString(yearString.mid(minus.length()), 4, readLength); |
2025 | if (readLength > 0 && value >= 0) { |
2026 | readLength = readLength + minus.length(); |
2027 | return value * -1; |
2028 | } else { |
2029 | return value; |
2030 | } |
2031 | } |
2032 | |
2033 | return d->integerFromString(yearString, 4, readLength); |
2034 | } |
2035 | |
2036 | int KCalendarSystem::monthStringToInteger(const QString &monthString, int &readLength) const |
2037 | { |
2038 | Q_D(const KCalendarSystem); |
2039 | return d->integerFromString(monthString, 2, readLength); |
2040 | } |
2041 | |
2042 | int KCalendarSystem::dayStringToInteger(const QString &dayString, int &readLength) const |
2043 | { |
2044 | Q_D(const KCalendarSystem); |
2045 | return d->integerFromString(dayString, 2, readLength); |
2046 | } |
2047 | |
2048 | QString KCalendarSystem::formatDate(const QDate &fromDate, KLocale::DateFormat toFormat) const |
2049 | { |
2050 | if (!fromDate.isValid()) { |
2051 | return QString(); |
2052 | } |
2053 | |
2054 | if (toFormat == KLocale::FancyShortDate || toFormat == KLocale::FancyLongDate) { |
2055 | QDate now = KDateTime::currentLocalDate(); |
2056 | int daysToNow = fromDate.daysTo(now); |
2057 | switch (daysToNow) { |
2058 | case 0: |
2059 | return i18n("Today" ); |
2060 | case 1: |
2061 | return i18n("Yesterday" ); |
2062 | case 2: |
2063 | case 3: |
2064 | case 4: |
2065 | case 5: |
2066 | case 6: |
2067 | return weekDayName(fromDate); |
2068 | default: |
2069 | break; |
2070 | } |
2071 | } |
2072 | |
2073 | switch (toFormat) { |
2074 | case KLocale::LongDate: |
2075 | case KLocale::FancyLongDate: |
2076 | return formatDate(fromDate, locale()->dateFormat()); |
2077 | case KLocale::IsoDate: |
2078 | return formatDate(fromDate, QLatin1String("%Y-%m-%d" )); |
2079 | case KLocale::IsoWeekDate: |
2080 | return formatDate(fromDate, QLatin1String("%Y-W%V-%u" )); |
2081 | case KLocale::IsoOrdinalDate: |
2082 | return formatDate(fromDate, QLatin1String("%Y-%j" )); |
2083 | case KLocale::ShortDate: |
2084 | case KLocale::FancyShortDate: |
2085 | default: |
2086 | return formatDate(fromDate, locale()->dateFormatShort()); |
2087 | } |
2088 | |
2089 | } |
2090 | |
2091 | // NOT VIRTUAL - If override needed use shared-d |
2092 | QString KCalendarSystem::formatDate(const QDate &fromDate, const QString &toFormat, |
2093 | KLocale::DateTimeFormatStandard standard) const |
2094 | { |
2095 | return formatDate(fromDate, toFormat, locale()->dateTimeDigitSet(), standard); |
2096 | } |
2097 | |
2098 | // NOT VIRTUAL - If override needed use shared-d |
2099 | QString KCalendarSystem::formatDate(const QDate &fromDate, const QString &toFormat, KLocale::DigitSet digitSet, |
2100 | KLocale::DateTimeFormatStandard formatStandard) const |
2101 | { |
2102 | if (!isValid(fromDate) || toFormat.isEmpty()) { |
2103 | return QString(); |
2104 | } |
2105 | |
2106 | KDateTimeFormatter formatter; |
2107 | return formatter.formatDate(fromDate, toFormat, this, locale(), digitSet, formatStandard); |
2108 | } |
2109 | |
2110 | // NOT VIRTUAL - If override needed use shared-d |
2111 | QString KCalendarSystem::formatDate(const QDate &date, KLocale::DateTimeComponent component, |
2112 | KLocale::DateTimeComponentFormat format, |
2113 | KLocale::WeekNumberSystem weekNumberSystem) const |
2114 | { |
2115 | Q_D(const KCalendarSystem); |
2116 | |
2117 | switch (component) { |
2118 | case KLocale::Year: |
2119 | case KLocale::YearName: |
2120 | switch (format) { |
2121 | case KLocale::ShortName: |
2122 | case KLocale::NarrowName: |
2123 | case KLocale::ShortNumber: |
2124 | return formatDate(date, QLatin1String("%y" )); |
2125 | case KLocale::LongNumber: |
2126 | case KLocale::LongName: |
2127 | case KLocale::DefaultComponentFormat: |
2128 | default: |
2129 | return formatDate(date, QLatin1String("%Y" )); |
2130 | } |
2131 | case KLocale::Month: |
2132 | switch (format) { |
2133 | case KLocale::LongName: |
2134 | return monthName(date, KCalendarSystem::LongName); |
2135 | case KLocale::ShortName: |
2136 | return monthName(date, KCalendarSystem::ShortName); |
2137 | case KLocale::NarrowName: |
2138 | return monthName(date, KCalendarSystem::NarrowName); |
2139 | case KLocale::LongNumber: |
2140 | return formatDate(date, QLatin1String("%m" )); |
2141 | case KLocale::ShortNumber: |
2142 | case KLocale::DefaultComponentFormat: |
2143 | default: |
2144 | return formatDate(date, QLatin1String("%n" )); |
2145 | } |
2146 | case KLocale::MonthName: |
2147 | switch (format) { |
2148 | case KLocale::NarrowName: |
2149 | return monthName(date, KCalendarSystem::NarrowName); |
2150 | case KLocale::ShortName: |
2151 | case KLocale::ShortNumber: |
2152 | return monthName(date, KCalendarSystem::ShortName); |
2153 | case KLocale::LongName: |
2154 | case KLocale::LongNumber: |
2155 | case KLocale::DefaultComponentFormat: |
2156 | default: |
2157 | return monthName(date, KCalendarSystem::LongName); |
2158 | } |
2159 | case KLocale::Day: |
2160 | case KLocale::DayName: |
2161 | switch (format) { |
2162 | case KLocale::LongNumber: |
2163 | case KLocale::LongName: |
2164 | return formatDate(date, QLatin1String("%d" )); |
2165 | case KLocale::ShortName: |
2166 | case KLocale::NarrowName: |
2167 | case KLocale::ShortNumber: |
2168 | case KLocale::DefaultComponentFormat: |
2169 | default: |
2170 | return formatDate(date, QLatin1String("%e" )); |
2171 | } |
2172 | case KLocale::JulianDay: |
2173 | return d->stringFromInteger(date.toJulianDay(), 0); |
2174 | case KLocale::EraName: |
2175 | switch (format) { |
2176 | case KLocale::LongNumber: |
2177 | case KLocale::LongName: |
2178 | return eraName(date, KCalendarSystem::LongFormat); |
2179 | case KLocale::ShortName: |
2180 | case KLocale::NarrowName: |
2181 | case KLocale::ShortNumber: |
2182 | case KLocale::DefaultComponentFormat: |
2183 | default: |
2184 | return eraName(date, KCalendarSystem::ShortFormat); |
2185 | } |
2186 | case KLocale::EraYear: |
2187 | switch (format) { |
2188 | case KLocale::LongNumber: |
2189 | case KLocale::LongName: |
2190 | return eraYear(date, KCalendarSystem::LongFormat); |
2191 | case KLocale::ShortName: |
2192 | case KLocale::NarrowName: |
2193 | case KLocale::ShortNumber: |
2194 | case KLocale::DefaultComponentFormat: |
2195 | default: |
2196 | return eraYear(date, KCalendarSystem::ShortFormat); |
2197 | } |
2198 | case KLocale::YearInEra: |
2199 | switch (format) { |
2200 | case KLocale::LongNumber: |
2201 | case KLocale::LongName: |
2202 | return formatDate(date, QLatin1String("%4Ey" )); |
2203 | case KLocale::ShortName: |
2204 | case KLocale::NarrowName: |
2205 | case KLocale::ShortNumber: |
2206 | case KLocale::DefaultComponentFormat: |
2207 | default: |
2208 | return formatDate(date, QLatin1String("%Ey" )); |
2209 | } |
2210 | case KLocale::DayOfYear: |
2211 | case KLocale::DayOfYearName: |
2212 | switch (format) { |
2213 | case KLocale::LongNumber: |
2214 | case KLocale::LongName: |
2215 | return formatDate(date, QLatin1String("%j" )); |
2216 | case KLocale::ShortName: |
2217 | case KLocale::NarrowName: |
2218 | case KLocale::ShortNumber: |
2219 | case KLocale::DefaultComponentFormat: |
2220 | default: |
2221 | return formatDate(date, QLatin1String("%-j" )); |
2222 | } |
2223 | case KLocale::DayOfWeek: |
2224 | switch (format) { |
2225 | case KLocale::LongName: |
2226 | return weekDayName(date, KCalendarSystem::LongDayName); |
2227 | case KLocale::ShortName: |
2228 | return weekDayName(date, KCalendarSystem::ShortDayName); |
2229 | case KLocale::NarrowName: |
2230 | return weekDayName(date, KCalendarSystem::NarrowDayName); |
2231 | case KLocale::LongNumber: |
2232 | case KLocale::ShortNumber: |
2233 | case KLocale::DefaultComponentFormat: |
2234 | default: |
2235 | return formatDate(date, QLatin1String("%-u" )); |
2236 | } |
2237 | case KLocale::DayOfWeekName: |
2238 | switch (format) { |
2239 | case KLocale::NarrowName: |
2240 | return weekDayName(date, KCalendarSystem::NarrowDayName); |
2241 | case KLocale::ShortName: |
2242 | case KLocale::ShortNumber: |
2243 | return weekDayName(date, KCalendarSystem::ShortDayName); |
2244 | case KLocale::LongName: |
2245 | case KLocale::LongNumber: |
2246 | case KLocale::DefaultComponentFormat: |
2247 | default: |
2248 | return weekDayName(date, KCalendarSystem::LongDayName); |
2249 | } |
2250 | case KLocale::Week: |
2251 | switch (format) { |
2252 | case KLocale::LongNumber: |
2253 | case KLocale::LongName: |
2254 | return d->stringFromInteger(week(date, weekNumberSystem, 0), 2, QLatin1Char('0')); |
2255 | case KLocale::ShortName: |
2256 | case KLocale::NarrowName: |
2257 | case KLocale::ShortNumber: |
2258 | case KLocale::DefaultComponentFormat: |
2259 | default: |
2260 | return d->stringFromInteger(week(date, weekNumberSystem, 0), 0, QLatin1Char('0')); |
2261 | } |
2262 | case KLocale::WeekYear: { |
2263 | int weekYear; |
2264 | QDate yearDate; |
2265 | week(date, weekNumberSystem, &weekYear); |
2266 | setDate(yearDate, weekYear, 1, 1); |
2267 | return formatDate(yearDate, KLocale::Year, format); |
2268 | } |
2269 | case KLocale::MonthsInYear: |
2270 | switch (format) { |
2271 | case KLocale::LongNumber: |
2272 | case KLocale::LongName: |
2273 | return d->stringFromInteger(monthsInYear(date), 2, QLatin1Char('0')); |
2274 | case KLocale::ShortName: |
2275 | case KLocale::NarrowName: |
2276 | case KLocale::ShortNumber: |
2277 | case KLocale::DefaultComponentFormat: |
2278 | default: |
2279 | return d->stringFromInteger(monthsInYear(date), 0, QLatin1Char('0')); |
2280 | } |
2281 | case KLocale::WeeksInYear: |
2282 | switch (format) { |
2283 | case KLocale::LongNumber: |
2284 | case KLocale::LongName: |
2285 | return d->stringFromInteger(weeksInYear(date), 2, QLatin1Char('0')); |
2286 | case KLocale::ShortName: |
2287 | case KLocale::NarrowName: |
2288 | case KLocale::ShortNumber: |
2289 | case KLocale::DefaultComponentFormat: |
2290 | default: |
2291 | return d->stringFromInteger(weeksInYear(date), 0, QLatin1Char('0')); |
2292 | } |
2293 | case KLocale::DaysInYear: |
2294 | switch (format) { |
2295 | case KLocale::LongNumber: |
2296 | case KLocale::LongName: |
2297 | return d->stringFromInteger(daysInYear(date), 3, QLatin1Char('0')); |
2298 | case KLocale::ShortName: |
2299 | case KLocale::NarrowName: |
2300 | case KLocale::ShortNumber: |
2301 | case KLocale::DefaultComponentFormat: |
2302 | default: |
2303 | return d->stringFromInteger(daysInYear(date), 0, QLatin1Char('0')); |
2304 | } |
2305 | case KLocale::DaysInMonth: |
2306 | switch (format) { |
2307 | case KLocale::LongNumber: |
2308 | case KLocale::LongName: |
2309 | return d->stringFromInteger(daysInMonth(date), 2, QLatin1Char('0')); |
2310 | case KLocale::ShortName: |
2311 | case KLocale::NarrowName: |
2312 | case KLocale::ShortNumber: |
2313 | case KLocale::DefaultComponentFormat: |
2314 | default: |
2315 | return d->stringFromInteger(daysInMonth(date), 0, QLatin1Char('0')); |
2316 | } |
2317 | case KLocale::DaysInWeek: |
2318 | switch (format) { |
2319 | case KLocale::LongNumber: |
2320 | case KLocale::LongName: |
2321 | case KLocale::ShortName: |
2322 | case KLocale::NarrowName: |
2323 | case KLocale::ShortNumber: |
2324 | case KLocale::DefaultComponentFormat: |
2325 | default: |
2326 | return d->stringFromInteger(d->daysInWeek(), 0); |
2327 | } |
2328 | default: |
2329 | return QString(); |
2330 | } |
2331 | } |
2332 | |
2333 | QDate KCalendarSystem::readDate(const QString &str, bool *ok) const |
2334 | { |
2335 | //Try each standard format in turn, start with the locale ones, |
2336 | //then the well defined standards |
2337 | QDate date = readDate(str, KLocale::ShortFormat, ok); |
2338 | if (!isValid(date)) { |
2339 | date = readDate(str, KLocale::NormalFormat, ok); |
2340 | if (!isValid(date)) { |
2341 | date = readDate(str, KLocale::IsoFormat, ok); |
2342 | if (!isValid(date)) { |
2343 | date = readDate(str, KLocale::IsoWeekFormat, ok); |
2344 | if (!isValid(date)) { |
2345 | date = readDate(str, KLocale::IsoOrdinalFormat, ok); |
2346 | } |
2347 | } |
2348 | } |
2349 | } |
2350 | |
2351 | return date; |
2352 | } |
2353 | |
2354 | QDate KCalendarSystem::readDate(const QString &str, KLocale::ReadDateFlags flags, bool *ok) const |
2355 | { |
2356 | Q_D(const KCalendarSystem); |
2357 | |
2358 | if (flags & KLocale::ShortFormat) { |
2359 | return readDate(str, locale()->dateFormatShort(), ok); |
2360 | } else if (flags & KLocale::NormalFormat) { |
2361 | return readDate(str, locale()->dateFormat(), ok); |
2362 | } else if (flags & KLocale::IsoFormat) { |
2363 | return readDate(str, QLatin1String("%Y-%m-%d" ), ok); |
2364 | } else if (flags & KLocale::IsoWeekFormat) { |
2365 | return readDate(str, QLatin1String("%Y-W%V-%u" ), ok); |
2366 | } else if (flags & KLocale::IsoOrdinalFormat) { |
2367 | return readDate(str, QLatin1String("%Y-%j" ), ok); |
2368 | } |
2369 | return d->invalidDate(); |
2370 | } |
2371 | |
2372 | QDate KCalendarSystem::readDate(const QString &inputString, const QString &formatString, bool *ok) const |
2373 | { |
2374 | return readDate(inputString, formatString, ok, KLocale::KdeFormat); |
2375 | } |
2376 | |
2377 | // NOT VIRTUAL - If override needed use shared-d |
2378 | QDate KCalendarSystem::readDate(const QString &inputString, const QString &formatString, bool *ok, |
2379 | KLocale::DateTimeFormatStandard formatStandard) const |
2380 | { |
2381 | KDateTimeParser parser; |
2382 | QDate resultDate = parser.parseDate(inputString, formatString, this, locale(), locale()->dateTimeDigitSet(), formatStandard); |
2383 | if (ok) { |
2384 | *ok = resultDate.isValid(); |
2385 | } |
2386 | return resultDate; |
2387 | } |
2388 | |
2389 | // NOT VIRTUAL - If override needed use shared-d |
2390 | int KCalendarSystem::shortYearWindowStartYear() const |
2391 | { |
2392 | Q_D(const KCalendarSystem); |
2393 | |
2394 | return d->shortYearWindowStartYear(); |
2395 | } |
2396 | |
2397 | // NOT VIRTUAL - If override needed use shared-d |
2398 | int KCalendarSystem::applyShortYearWindow(int inputYear) const |
2399 | { |
2400 | Q_D(const KCalendarSystem); |
2401 | |
2402 | return d->applyShortYearWindow(inputYear); |
2403 | } |
2404 | |
2405 | int KCalendarSystem::weekStartDay() const |
2406 | { |
2407 | return locale()->weekStartDay(); |
2408 | } |
2409 | |
2410 | // Dummy version using Gregorian as an example |
2411 | // This method MUST be re-implemented in any new Calendar System |
2412 | // The implementation MUST NOT do validity checking on date ranges, all calls to this function MUST |
2413 | // instead be wrapped in validity checks, as sometimes we want this to work outside the public valid |
2414 | // range, i.e. to allow us to internally set dates of 1/1/10000 which are not publically valid but |
2415 | // are required for internal maths |
2416 | bool KCalendarSystem::julianDayToDate(int jd, int &year, int &month, int &day) const |
2417 | { |
2418 | // Formula from The Calendar FAQ by Claus Tondering |
2419 | // http://www.tondering.dk/claus/cal/node3.html#SECTION003161000000000000000 |
2420 | // NOTE: Coded from scratch from mathematical formulas, not copied from |
2421 | // the Boost licensed source code |
2422 | |
2423 | int a = jd + 32044; |
2424 | int b = ((4 * a) + 3) / 146097; |
2425 | int c = a - ((146097 * b) / 4); |
2426 | int d = ((4 * c) + 3) / 1461; |
2427 | int e = c - ((1461 * d) / 4); |
2428 | int m = ((5 * e) + 2) / 153; |
2429 | day = e - (((153 * m) + 2) / 5) + 1; |
2430 | month = m + 3 - (12 * (m / 10)); |
2431 | year = (100 * b) + d - 4800 + (m / 10); |
2432 | |
2433 | // If year is -ve then is BC. In Gregorian there is no year 0, but the maths |
2434 | // is easier if we pretend there is, so internally year of 0 = 1BC = -1 outside |
2435 | if (year < 1) { |
2436 | year = year - 1; |
2437 | } |
2438 | |
2439 | return true; |
2440 | } |
2441 | |
2442 | // Dummy version using Gregorian as an example |
2443 | // This method MUST be re-implemented in any new Calendar System |
2444 | // The implementation MUST NOT do validity checking on date ranges, all calls to this function MUST |
2445 | // instead be wrapped in validity checks, as sometimes we want this to work outside the public valid |
2446 | // range, i.e. to allow us to internally set dates of 1/1/10000 which are not publically valid but |
2447 | // are required for internal maths |
2448 | bool KCalendarSystem::dateToJulianDay(int year, int month, int day, int &jd) const |
2449 | { |
2450 | // Formula from The Calendar FAQ by Claus Tondering |
2451 | // http://www.tondering.dk/claus/cal/node3.html#SECTION003161000000000000000 |
2452 | // NOTE: Coded from scratch from mathematical formulas, not copied from |
2453 | // the Boost licensed source code |
2454 | |
2455 | // If year is -ve then is BC. In Gregorian there is no year 0, but the maths |
2456 | // is easier if we pretend there is, so internally year of -1 = 1BC = 0 internally |
2457 | int y; |
2458 | if (year < 1) { |
2459 | y = year + 1; |
2460 | } else { |
2461 | y = year; |
2462 | } |
2463 | |
2464 | int a = (14 - month) / 12; |
2465 | y = y + 4800 - a; |
2466 | int m = month + (12 * a) - 3; |
2467 | |
2468 | jd = day |
2469 | + (((153 * m) + 2) / 5) |
2470 | + (365 * y) |
2471 | + (y / 4) |
2472 | - (y / 100) |
2473 | + (y / 400) |
2474 | - 32045; |
2475 | |
2476 | return true; |
2477 | } |
2478 | |
2479 | const KLocale * KCalendarSystem::locale() const |
2480 | { |
2481 | Q_D(const KCalendarSystem); |
2482 | |
2483 | return d->locale(); |
2484 | } |
2485 | |
2486 | // Deprecated |
2487 | void KCalendarSystem::setMaxMonthsInYear(int maxMonths) |
2488 | { |
2489 | Q_UNUSED(maxMonths) |
2490 | } |
2491 | |
2492 | // Deprecated |
2493 | void KCalendarSystem::setMaxDaysInWeek(int maxDays) |
2494 | { |
2495 | Q_UNUSED(maxDays) |
2496 | } |
2497 | |
2498 | // Deprecated |
2499 | void KCalendarSystem::setHasYear0(bool hasYear0) |
2500 | { |
2501 | Q_UNUSED(hasYear0) |
2502 | } |
2503 | |