[PATCH 19/23] kcalendarsystem: Move most week related code out ouf the way of regular calendar system code.
Jon Severinsson
jon at severinsson.net
Fri Oct 12 15:13:54 UTC 2012
This commit changes no code whatsoever, it only moves it around a bit so the rest becomes more manageable.
---
kdecore/CMakeLists.txt | 1 +
kdecore/date/kcalendarsystem.cpp | 232 --------------------------
kdecore/date/kcalendarsystem.h | 306 +++++++++++++++++-----------------
kdecore/date/kcalendarsystemweek.cpp | 254 ++++++++++++++++++++++++++++
4 filer ändrade, 408 tillägg(+), 385 borttagningar(-)
create mode 100644 kdecore/date/kcalendarsystemweek.cpp
diff --git a/kdecore/CMakeLists.txt b/kdecore/CMakeLists.txt
index ed8471f..068919f 100644
--- a/kdecore/CMakeLists.txt
+++ b/kdecore/CMakeLists.txt
@@ -163,6 +163,7 @@ set(kdecore_LIB_SRCS
date/kcalendarsystemjulian.cpp
date/kcalendarsystemminguo.cpp
date/kcalendarsystemthai.cpp
+ date/kcalendarsystemweek.cpp
date/kdatetime.cpp
date/kdatetimeformatter.cpp
date/kdatetimeparser.cpp
diff --git a/kdecore/date/kcalendarsystem.cpp b/kdecore/date/kcalendarsystem.cpp
index 92db979..69f1494 100644
--- a/kdecore/date/kcalendarsystem.cpp
+++ b/kdecore/date/kcalendarsystem.cpp
@@ -149,120 +149,6 @@ KCalendarSystemPrivate::~KCalendarSystemPrivate()
delete m_eraList;
}
-int KCalendarSystemPrivate::isoWeekNumber(const QDate &date, int *yearNum) const
-{
- int y, m, d;
- q->julianDayToDate(date.toJulianDay(), y, m, d);
-
- QDate firstDayWeek1, lastDay;
- int week;
- int weekDay1, dayOfWeek1InYear;
-
- // let's guess 1st day of 1st week
- firstDayWeek1 = firstDayOfYear(y);
- weekDay1 = q->dayOfWeek(firstDayWeek1);
-
- // iso 8601: week 1 is the first containing thursday and week starts on monday
- if (weekDay1 > 4 /*Thursday*/) {
- firstDayWeek1 = q->addDays(firstDayWeek1 , 7 - weekDay1 + 1); // next monday
- }
-
- dayOfWeek1InYear = dayOfYear(firstDayWeek1);
-
- // our date in prev year's week
- if (dayOfYear(date) < dayOfWeek1InYear) {
- if (yearNum) {
- *yearNum = addYears(y, - 1);
- }
- return isoWeeksInYear(addYears(y, - 1));
- }
-
- // let's check if its last week belongs to next year
- lastDay = lastDayOfYear(y);
-
- // if our date is in last week && 1st week in next year has thursday
- if ((dayOfYear(date) >= daysInYear(y) - q->dayOfWeek(lastDay) + 1)
- && q->dayOfWeek(lastDay) < 4) {
- if (yearNum) {
- * yearNum = addYears(y, 1);
- }
- week = 1;
- } else {
- // To calculate properly the number of weeks from day a to x let's make a day 1 of week
- if (weekDay1 < 5) {
- firstDayWeek1 = q->addDays(firstDayWeek1, -(weekDay1 - 1));
- }
-
- if (yearNum) {
- * yearNum = y;
- }
-
- week = firstDayWeek1.daysTo(date) / 7 + 1;
- }
-
- return week;
-}
-
-int KCalendarSystemPrivate::regularWeekNumber(const QDate &date, int weekStartDay, int firstWeekNumber, int *weekYear) const
-{
- int y, m, d;
- q->julianDayToDate(date.toJulianDay(), y, m, d);
-
- int firstWeekDayOffset = (q->dayOfWeek(date) - weekStartDay + 7) % 7;
- int dayInYear = date.toJulianDay() - firstDayOfYear(y).toJulianDay(); // 0 indexed
- int week = ((dayInYear - firstWeekDayOffset + 7) / 7);
-
- if (q->dayOfWeek(firstDayOfYear(y)) != weekStartDay) {
- week = week + firstWeekNumber;
- }
-
- if (week < 1) {
- y = y - 1;
- week = regularWeeksInYear(y, weekStartDay, firstWeekNumber);
- }
-
- if (weekYear) {
- *weekYear = y;
- }
-
- return week;
-}
-
-int KCalendarSystemPrivate::simpleWeekNumber(const QDate &date, int *yearNum) const
-{
- int y, m, d;
- q->julianDayToDate(date.toJulianDay(), y, m, d);
- if (yearNum) {
- *yearNum = y;
- }
- return ((date.toJulianDay() - firstDayOfYear(y).toJulianDay()) / 7) + 1;
-}
-
-int KCalendarSystemPrivate::isoWeeksInYear(int year) const
-{
- QDate lastDayOfThisYear = lastDayOfYear(year);
-
- int weekYear = year;
- int lastWeekInThisYear = isoWeekNumber(lastDayOfThisYear, &weekYear);
-
- // If error, or the last day of the year is in the first week of next year use the week before
- if (lastWeekInThisYear < 1 || weekYear != year) {
- lastWeekInThisYear = isoWeekNumber(q->addDays(lastDayOfThisYear, -7), &weekYear);
- }
-
- return lastWeekInThisYear;
-}
-
-int KCalendarSystemPrivate::regularWeeksInYear(int year, int weekStartDay, int firstWeekNumber) const
-{
- return regularWeekNumber(lastDayOfYear(year), weekStartDay, firstWeekNumber, 0);
-}
-
-int KCalendarSystemPrivate::simpleWeeksInYear(int year) const
-{
- return simpleWeekNumber(lastDayOfYear(year), 0);
-}
-
// Reimplement if special maths handling required, e.g. Hebrew.
// Works for calendars with constant number of months, or where leap month is last month of year
// Will not work for Hebrew or others where leap month is inserted in middle of year
@@ -790,50 +676,6 @@ bool KCalendarSystem::isValid(const QString &eraName, int yearInEra, int month,
return (era.isValid() && isValid(era.year(yearInEra), month, day));
}
-// NOT VIRTUAL - If override needed use shared-d
-bool KCalendarSystem::isValidIsoWeekDate(int year, int isoWeekNumber, int dayOfIsoWeek) const
-{
- Q_D(const KCalendarSystem);
-
- //Tests Year value in standard YMD isValid()
- if (!isValid(year, 1, 1)) {
- return false;
- }
-
- //Test Week Number falls in valid range for this year
- int weeksInThisYear = weeksInYear(year);
- if (isoWeekNumber < 1 || isoWeekNumber > weeksInThisYear) {
- return false;
- }
-
- //Test Day of Week Number falls in valid range
- if (dayOfIsoWeek < 1 || dayOfIsoWeek > 7) {
- return false;
- }
-
- //If not in earliest or latest years then all OK
- //Otherwise need to check don't fall into previous or next year that would be invalid
- if (year == d->earliestValidYear() && isoWeekNumber == 1) {
- //If firstDayOfYear falls on or before Thursday then firstDayOfYear falls in week 1 this
- //year and if wanted dayOfIsoWeek falls before firstDayOfYear then falls in previous year
- //and so in invalid year
- int dowFirstDay = dayOfWeek(d->firstDayOfYear(year));
- if (dowFirstDay <= 4 && dayOfIsoWeek < dowFirstDay) {
- return false;
- }
- } else if (year == d->latestValidYear() && isoWeekNumber == weeksInThisYear) {
- //If lastDayOfYear falls on or after Thursday then lastDayOfYear falls in last week this
- //year and if wanted dayOfIsoWeek falls after lastDayOfYear then falls in next year
- //and so in invalid year
- int dowLastDay = dayOfWeek(d->lastDayOfYear(year));
- if (dowLastDay >= 4 && dayOfIsoWeek > dowLastDay) {
- return false;
- }
- }
-
- return true;
-}
-
bool KCalendarSystem::setDate(QDate &date, int year, int month, int day) const
{
date = QDate();
@@ -879,35 +721,6 @@ bool KCalendarSystem::setDate(QDate &date, QString eraName, int yearInEra, int m
return (era.isValid() && setDate(date, era.year(yearInEra), month, day));
}
-// NOT VIRTUAL - If override needed use shared-d
-bool KCalendarSystem::setDateIsoWeek(QDate &date, int year, int isoWeekNumber, int dayOfIsoWeek) const
-{
- Q_D(const KCalendarSystem);
-
- date = QDate();
-
- if (isValidIsoWeekDate(year, isoWeekNumber, dayOfIsoWeek)) {
-
- QDate calcDate = d->firstDayOfYear(year);
- int dowFirstDayOfYear = dayOfWeek(calcDate);
-
- int daysToAdd = (7 * (isoWeekNumber - 1)) + dayOfIsoWeek;
-
- if (dowFirstDayOfYear <= 4) {
- calcDate = calcDate.addDays(daysToAdd - dowFirstDayOfYear);
- } else {
- calcDate = calcDate.addDays(7 + daysToAdd - dowFirstDayOfYear);
- }
-
- if (isValid(calcDate)) {
- date = calcDate;
- return true;
- }
- }
-
- return false;
-}
-
// Deprecated
bool KCalendarSystem::setYMD(QDate &date, int year, int month, int day) const
{
@@ -1168,28 +981,6 @@ int KCalendarSystem::monthsInYear(int year) const
return -1;
}
-int KCalendarSystem::weeksInYear(int year, KLocale::WeekNumberSystem weekNumberSystem) const
-{
- Q_D(const KCalendarSystem);
-
- if (!isValid(year, 1, 1))
- return -1;
-
- switch (weekNumberSystem) {
- case KLocale::IsoWeekNumber:
- return d->isoWeeksInYear(year);
- case KLocale::FirstFullWeek:
- return d->regularWeeksInYear(year, locale()->weekStartDay(), 0);
- case KLocale::FirstPartialWeek:
- return d->regularWeeksInYear(year, locale()->weekStartDay(), 1);
- case KLocale::SimpleWeek:
- return d->simpleWeeksInYear(year);
- case KLocale::DefaultWeekNumber:
- default:
- return weeksInYear(year, locale()->weekNumberSystem());
- }
-}
-
int KCalendarSystem::daysInYear(const QDate &date) const
{
Q_D(const KCalendarSystem);
@@ -1249,29 +1040,6 @@ int KCalendarSystem::dayOfYear(const QDate &date) const
return -1;
}
-
-int KCalendarSystem::week(const QDate &date, KLocale::WeekNumberSystem weekNumberSystem, int *yearNum) const
-{
- Q_D(const KCalendarSystem);
-
- if (!isValid(date))
- return -1;
-
- switch (weekNumberSystem) {
- case KLocale::IsoWeekNumber:
- return d->isoWeekNumber(date, yearNum);
- case KLocale::FirstFullWeek:
- return d->regularWeekNumber(date, locale()->weekStartDay(), 0, yearNum);
- case KLocale::FirstPartialWeek:
- return d->regularWeekNumber(date, locale()->weekStartDay(), 1, yearNum);
- case KLocale::SimpleWeek:
- return d->simpleWeekNumber(date, yearNum);
- case KLocale::DefaultWeekNumber:
- default:
- return week(date, locale()->weekNumberSystem(), yearNum);
- }
-}
-
bool KCalendarSystem::isLeapYear(int year) const
{
Q_D(const KCalendarSystem);
diff --git a/kdecore/date/kcalendarsystem.h b/kdecore/date/kcalendarsystem.h
index 742713a..1635a68 100644
--- a/kdecore/date/kcalendarsystem.h
+++ b/kdecore/date/kcalendarsystem.h
@@ -226,18 +226,6 @@ public:
bool isValid(const QString &eraName, int yearInEra, int month, int day) const;
/**
- * @since 4.4
- *
- * Returns whether a given date is valid in this calendar system.
- *
- * @param year the year portion of the date to check
- * @param isoWeekNumber the ISO week portion of the date to check
- * @param dayOfIsoWeek the day of week portion of the date to check
- * @return @c true if the date is valid, @c false otherwise
- */
- bool isValidIsoWeekDate(int year, int isoWeekNumber, int dayOfIsoWeek) const;
-
- /**
* Returns whether a given date is valid in this calendar system.
*
* @param date the date to check
@@ -291,19 +279,6 @@ public:
bool setDate(QDate &date, QString eraName, int yearInEra, int month, int day) const;
/**
- * @since 4.4
- *
- * Set a date using the year number, ISO week number and day of week number.
- *
- * @param date date to change
- * @param year year
- * @param isoWeekNumber ISO week of year
- * @param dayOfIsoWeek day of week Mon..Sun (1..7)
- * @return @c true if the date is valid, @c false otherwise
- */
- bool setDateIsoWeek(QDate &date, int year, int isoWeekNumber, int dayOfIsoWeek) const;
-
- /**
* @deprecated Use setDate() instead
*
* Some implementations reject year range 00 to 99, but extended date
@@ -510,35 +485,6 @@ public:
int monthsInYear(int year) const;
/**
- * @since 4.7
- *
- * Returns the number of Weeks in a year using the specified Week Number System.
- *
- * @see week()
- * @see formatDate()
- * @param date the date to obtain year from
- * @param weekNumberSystem the week number system to use
- * @return number of weeks in the year, -1 if date invalid
- */
- inline int weeksInYear(const QDate &date, KLocale::WeekNumberSystem weekNumberSystem = KLocale::DefaultWeekNumber) const
- {
- return isValid(date) ? weeksInYear(year(date), weekNumberSystem) : -1;
- }
-
- /**
- * @since 4.7
- *
- * Returns the number of Weeks in a year using the specified Week Number System.
- *
- * @see week()
- * @see formatDate()
- * @param year the year
- * @param weekNumberSystem the week number system to use
- * @return number of weeks in the year, -1 if date invalid
- */
- int weeksInYear(int year, KLocale::WeekNumberSystem weekNumberSystem = KLocale::DefaultWeekNumber) const;
-
- /**
* Returns the number of days in the given year.
*
* @param date the date to obtain year from
@@ -578,26 +524,6 @@ public:
int daysInMonth(int year, int month) const;
/**
- * @deprecated use 7 instead
- *
- * Returns the number of days in the given week.
- *
- * @note This API is misdesigned, does not work, and have never worked. The
- * number of days in a week does not depend on the calendar system or
- * the date, only on the week number system used. For all week number
- * system ever supported by @c KCalendarSystem it returns, and has
- * always returned, @c 7.
- *
- * @param date ignored
- * @return 7
- */
- KDECORE_DEPRECATED inline int daysInWeek(const QDate &date) const
- {
- Q_UNUSED(date);
- return 7;
- }
-
- /**
* Returns the day number of year for the given date
*
* The days are numbered 1..daysInYear()
@@ -608,85 +534,6 @@ public:
virtual int dayOfYear(const QDate &date) const;
/**
- * Returns the weekday number for the given date
- *
- * The weekdays are numbered 1..7 for Monday..Sunday.
- *
- * This value is @em not affected by the value of weekStartDay()
- *
- * @param date the date to obtain day from
- * @return day of week number, -1 if input date not valid
- */
- inline int dayOfWeek(const QDate &date) const
- {
- return isValid(date) ? date.dayOfWeek() : -1;
- }
-
- /**
- * @deprecated use week() instead
- *
- * Returns the ISO week number for the given date.
- *
- * ISO 8601 defines the first week of the year as the week containing the first Thursday.
- * See http://en.wikipedia.org/wiki/ISO_8601 and http://en.wikipedia.org/wiki/ISO_week_date
- *
- * If the date falls in the last week of the previous year or the first week of the following
- * year, then the yearNum returned will be set to the appropriate year.
- *
- * @param date the date to obtain week from
- * @param yearNum returns the year the date belongs to
- * @return ISO week number, -1 if input date invalid
- */
- KDECORE_DEPRECATED inline int weekNumber(const QDate &date, int *yearNum = 0) const
- {
- return week(date, KLocale::IsoWeekNumber, yearNum);
- }
-
- /**
- * Returns the localized Week Number for the date.
- *
- * This may be ISO, US, or any other supported week numbering scheme. If
- * you specifically require the ISO Week or any other scheme, you should use
- * the week(KLocale::WeekNumberSystem) form.
- *
- * If the date falls in the last week of the previous year or the first
- * week of the following year, then the yearNum returned will be set to the
- * appropriate year.
- *
- * @see weeksInYear()
- * @see formatDate()
- * @param date the date to obtain week from
- * @param yearNum returns the year the date belongs to
- * @return localized week number, -1 if input date invalid
- */
- inline int week(const QDate &date, int *yearNum) const
- {
- return week(date, KLocale::DefaultWeekNumber, yearNum);
- }
-
- /**
- * Returns the Week Number for the date in the required Week Number System.
- *
- * Unless you want a specific Week Number System (e.g. ISO Week), you should
- * use the localized Week Number form of week().
- *
- * If the date falls in the last week of the previous year or the first
- * week of the following year, then the yearNum returned will be set to the
- * appropriate year.
- *
- * Technically, the ISO Week Number only applies to the ISO/Gregorian Calendar
- * System, but the same rules will be applied to the current Calendar System.
- *
- * @see weeksInYear()
- * @see formatDate()
- * @param date the date to obtain week from
- * @param weekNumberSystem the Week Number System to use
- * @param yearNum returns the year the date belongs to
- * @return week number, -1 if input date invalid
- */
- int week(const QDate &date, KLocale::WeekNumberSystem weekNumberSystem = KLocale::DefaultWeekNumber, int *yearNum = 0) const;
-
- /**
* Returns whether a given year is a leap year.
*
* Input year must be checked for validity in current Calendar System prior to calling, no
@@ -1390,6 +1237,159 @@ public:
int applyShortYearWindow(int inputYear) const;
/**
+ * Returns the weekday number for the given date
+ *
+ * The weekdays are numbered 1..7 for Monday..Sunday.
+ *
+ * This value is @em not affected by the value of weekStartDay()
+ *
+ * @param date the date to obtain day from
+ * @return day of week number, -1 if input date not valid
+ */
+ inline int dayOfWeek(const QDate &date) const
+ {
+ return isValid(date) ? date.dayOfWeek() : -1;
+ }
+
+ /**
+ * Returns the Week Number for the date in the required Week Number System.
+ *
+ * Unless you want a specific Week Number System (e.g. ISO Week), you should
+ * use the localized Week Number form of week().
+ *
+ * If the date falls in the last week of the previous year or the first
+ * week of the following year, then the yearNum returned will be set to the
+ * appropriate year.
+ *
+ * Technically, the ISO Week Number only applies to the ISO/Gregorian Calendar
+ * System, but the same rules will be applied to the current Calendar System.
+ *
+ * @see weeksInYear()
+ * @see formatDate()
+ * @param date the date to obtain week from
+ * @param weekNumberSystem the Week Number System to use
+ * @param yearNum returns the year the date belongs to
+ * @return week number, -1 if input date invalid
+ */
+ int week(const QDate &date, KLocale::WeekNumberSystem weekNumberSystem = KLocale::DefaultWeekNumber, int *yearNum = 0) const;
+
+ /**
+ * Returns the localized Week Number for the date.
+ *
+ * This may be ISO, US, or any other supported week numbering scheme. If
+ * you specifically require the ISO Week or any other scheme, you should use
+ * the week(KLocale::WeekNumberSystem) form.
+ *
+ * If the date falls in the last week of the previous year or the first
+ * week of the following year, then the yearNum returned will be set to the
+ * appropriate year.
+ *
+ * @see weeksInYear()
+ * @see formatDate()
+ * @param date the date to obtain week from
+ * @param yearNum returns the year the date belongs to
+ * @return localized week number, -1 if input date invalid
+ */
+ inline int week(const QDate &date, int *yearNum) const
+ {
+ return week(date, KLocale::DefaultWeekNumber, yearNum);
+ }
+
+ /**
+ * @deprecated use week() instead
+ *
+ * Returns the ISO week number for the given date.
+ *
+ * ISO 8601 defines the first week of the year as the week containing the first Thursday.
+ * See http://en.wikipedia.org/wiki/ISO_8601 and http://en.wikipedia.org/wiki/ISO_week_date
+ *
+ * If the date falls in the last week of the previous year or the first week of the following
+ * year, then the yearNum returned will be set to the appropriate year.
+ *
+ * @param date the date to obtain week from
+ * @param yearNum returns the year the date belongs to
+ * @return ISO week number, -1 if input date invalid
+ */
+ KDECORE_DEPRECATED inline int weekNumber(const QDate &date, int *yearNum = 0) const
+ {
+ return week(date, KLocale::IsoWeekNumber, yearNum);
+ }
+
+ /**
+ * @since 4.7
+ *
+ * Returns the number of Weeks in a year using the specified Week Number System.
+ *
+ * @see week()
+ * @see formatDate()
+ * @param date the date to obtain year from
+ * @param weekNumberSystem the week number system to use
+ * @return number of weeks in the year, -1 if date invalid
+ */
+ inline int weeksInYear(const QDate &date, KLocale::WeekNumberSystem weekNumberSystem = KLocale::DefaultWeekNumber) const
+ {
+ return isValid(date) ? weeksInYear(year(date), weekNumberSystem) : -1;
+ }
+
+ /**
+ * @since 4.7
+ *
+ * Returns the number of Weeks in a year using the specified Week Number System.
+ *
+ * @see week()
+ * @see formatDate()
+ * @param year the year
+ * @param weekNumberSystem the week number system to use
+ * @return number of weeks in the year, -1 if date invalid
+ */
+ int weeksInYear(int year, KLocale::WeekNumberSystem weekNumberSystem = KLocale::DefaultWeekNumber) const;
+
+ /**
+ * @deprecated use 7 instead
+ *
+ * Returns the number of days in the given week.
+ *
+ * @note This API is misdesigned, does not work, and have never worked. The
+ * number of days in a week does not depend on the calendar system or
+ * the date, only on the week number system used. For all week number
+ * system ever supported by @c KCalendarSystem it returns, and has
+ * always returned, @c 7.
+ *
+ * @param date ignored
+ * @return 7
+ */
+ KDECORE_DEPRECATED inline int daysInWeek(const QDate &date) const
+ {
+ Q_UNUSED(date);
+ return 7;
+ }
+
+ /**
+ * @since 4.4
+ *
+ * Returns whether a given date is valid in this calendar system.
+ *
+ * @param year the year portion of the date to check
+ * @param isoWeekNumber the ISO week portion of the date to check
+ * @param dayOfIsoWeek the day of week portion of the date to check
+ * @return @c true if the date is valid, @c false otherwise
+ */
+ bool isValidIsoWeekDate(int year, int isoWeekNumber, int dayOfIsoWeek) const;
+
+ /**
+ * @since 4.4
+ *
+ * Set a date using the year number, ISO week number and day of week number.
+ *
+ * @param date date to change
+ * @param year year
+ * @param isoWeekNumber ISO week of year
+ * @param dayOfIsoWeek day of week Mon..Sun (1..7)
+ * @return @c true if the date is valid, @c false otherwise
+ */
+ bool setDateIsoWeek(QDate &date, int year, int isoWeekNumber, int dayOfIsoWeek) const;
+
+ /**
* Use this to determine which day is the first day of the week.
*
* Uses the calendar system's internal locale set when the instance was
diff --git a/kdecore/date/kcalendarsystemweek.cpp b/kdecore/date/kcalendarsystemweek.cpp
new file mode 100644
index 0000000..ba7fff4
--- /dev/null
+++ b/kdecore/date/kcalendarsystemweek.cpp
@@ -0,0 +1,254 @@
+/*
+ Copyright (c) 2002 Carlos Moro <cfmoro at correo.uniovi.es>
+ Copyright (c) 2002 Hans Petter Bieker <bieker at kde.org>
+ Copyright 2007, 2008, 2009, 2010 John Layt <john at layt.net>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kcalendarsystem.h"
+#include "kcalendarsystemprivate_p.h"
+
+
+int KCalendarSystemPrivate::isoWeekNumber(const QDate &date, int *yearNum) const
+{
+ int y, m, d;
+ q->julianDayToDate(date.toJulianDay(), y, m, d);
+
+ QDate firstDayWeek1, lastDay;
+ int week;
+ int weekDay1, dayOfWeek1InYear;
+
+ // let's guess 1st day of 1st week
+ firstDayWeek1 = firstDayOfYear(y);
+ weekDay1 = q->dayOfWeek(firstDayWeek1);
+
+ // iso 8601: week 1 is the first containing thursday and week starts on monday
+ if (weekDay1 > 4 /*Thursday*/) {
+ firstDayWeek1 = q->addDays(firstDayWeek1 , 7 - weekDay1 + 1); // next monday
+ }
+
+ dayOfWeek1InYear = dayOfYear(firstDayWeek1);
+
+ // our date in prev year's week
+ if (dayOfYear(date) < dayOfWeek1InYear) {
+ if (yearNum) {
+ *yearNum = addYears(y, - 1);
+ }
+ return isoWeeksInYear(addYears(y, - 1));
+ }
+
+ // let's check if its last week belongs to next year
+ lastDay = lastDayOfYear(y);
+
+ // if our date is in last week && 1st week in next year has thursday
+ if ((dayOfYear(date) >= daysInYear(y) - q->dayOfWeek(lastDay) + 1)
+ && q->dayOfWeek(lastDay) < 4) {
+ if (yearNum) {
+ * yearNum = addYears(y, 1);
+ }
+ week = 1;
+ } else {
+ // To calculate properly the number of weeks from day a to x let's make a day 1 of week
+ if (weekDay1 < 5) {
+ firstDayWeek1 = q->addDays(firstDayWeek1, -(weekDay1 - 1));
+ }
+
+ if (yearNum) {
+ * yearNum = y;
+ }
+
+ week = firstDayWeek1.daysTo(date) / 7 + 1;
+ }
+
+ return week;
+}
+
+int KCalendarSystemPrivate::regularWeekNumber(const QDate &date, int weekStartDay, int firstWeekNumber, int *weekYear) const
+{
+ int y, m, d;
+ q->julianDayToDate(date.toJulianDay(), y, m, d);
+
+ int firstWeekDayOffset = (q->dayOfWeek(date) - weekStartDay + 7) % 7;
+ int dayInYear = date.toJulianDay() - firstDayOfYear(y).toJulianDay(); // 0 indexed
+ int week = ((dayInYear - firstWeekDayOffset + 7) / 7);
+
+ if (q->dayOfWeek(firstDayOfYear(y)) != weekStartDay) {
+ week = week + firstWeekNumber;
+ }
+
+ if (week < 1) {
+ y = y - 1;
+ week = regularWeeksInYear(y, weekStartDay, firstWeekNumber);
+ }
+
+ if (weekYear) {
+ *weekYear = y;
+ }
+
+ return week;
+}
+
+int KCalendarSystemPrivate::simpleWeekNumber(const QDate &date, int *yearNum) const
+{
+ int y, m, d;
+ q->julianDayToDate(date.toJulianDay(), y, m, d);
+ if (yearNum) {
+ *yearNum = y;
+ }
+ return ((date.toJulianDay() - firstDayOfYear(y).toJulianDay()) / 7) + 1;
+}
+
+int KCalendarSystemPrivate::isoWeeksInYear(int year) const
+{
+ QDate lastDayOfThisYear = lastDayOfYear(year);
+
+ int weekYear = year;
+ int lastWeekInThisYear = isoWeekNumber(lastDayOfThisYear, &weekYear);
+
+ // If error, or the last day of the year is in the first week of next year use the week before
+ if (lastWeekInThisYear < 1 || weekYear != year) {
+ lastWeekInThisYear = isoWeekNumber(q->addDays(lastDayOfThisYear, -7), &weekYear);
+ }
+
+ return lastWeekInThisYear;
+}
+
+int KCalendarSystemPrivate::regularWeeksInYear(int year, int weekStartDay, int firstWeekNumber) const
+{
+ return regularWeekNumber(lastDayOfYear(year), weekStartDay, firstWeekNumber, 0);
+}
+
+int KCalendarSystemPrivate::simpleWeeksInYear(int year) const
+{
+ return simpleWeekNumber(lastDayOfYear(year), 0);
+}
+
+
+int KCalendarSystem::weeksInYear(int year, KLocale::WeekNumberSystem weekNumberSystem) const
+{
+ Q_D(const KCalendarSystem);
+
+ if (!isValid(year, 1, 1))
+ return -1;
+
+ switch (weekNumberSystem) {
+ case KLocale::IsoWeekNumber:
+ return d->isoWeeksInYear(year);
+ case KLocale::FirstFullWeek:
+ return d->regularWeeksInYear(year, locale()->weekStartDay(), 0);
+ case KLocale::FirstPartialWeek:
+ return d->regularWeeksInYear(year, locale()->weekStartDay(), 1);
+ case KLocale::SimpleWeek:
+ return d->simpleWeeksInYear(year);
+ case KLocale::DefaultWeekNumber:
+ default:
+ return weeksInYear(year, locale()->weekNumberSystem());
+ }
+}
+
+int KCalendarSystem::week(const QDate &date, KLocale::WeekNumberSystem weekNumberSystem, int *yearNum) const
+{
+ Q_D(const KCalendarSystem);
+
+ if (!isValid(date))
+ return -1;
+
+ switch (weekNumberSystem) {
+ case KLocale::IsoWeekNumber:
+ return d->isoWeekNumber(date, yearNum);
+ case KLocale::FirstFullWeek:
+ return d->regularWeekNumber(date, locale()->weekStartDay(), 0, yearNum);
+ case KLocale::FirstPartialWeek:
+ return d->regularWeekNumber(date, locale()->weekStartDay(), 1, yearNum);
+ case KLocale::SimpleWeek:
+ return d->simpleWeekNumber(date, yearNum);
+ case KLocale::DefaultWeekNumber:
+ default:
+ return week(date, locale()->weekNumberSystem(), yearNum);
+ }
+}
+
+bool KCalendarSystem::isValidIsoWeekDate(int year, int isoWeekNumber, int dayOfIsoWeek) const
+{
+ Q_D(const KCalendarSystem);
+
+ //Tests Year value in standard YMD isValid()
+ if (!isValid(year, 1, 1)) {
+ return false;
+ }
+
+ //Test Week Number falls in valid range for this year
+ int weeksInThisYear = weeksInYear(year);
+ if (isoWeekNumber < 1 || isoWeekNumber > weeksInThisYear) {
+ return false;
+ }
+
+ //Test Day of Week Number falls in valid range
+ if (dayOfIsoWeek < 1 || dayOfIsoWeek > 7) {
+ return false;
+ }
+
+ //If not in earliest or latest years then all OK
+ //Otherwise need to check don't fall into previous or next year that would be invalid
+ if (year == d->earliestValidYear() && isoWeekNumber == 1) {
+ //If firstDayOfYear falls on or before Thursday then firstDayOfYear falls in week 1 this
+ //year and if wanted dayOfIsoWeek falls before firstDayOfYear then falls in previous year
+ //and so in invalid year
+ int dowFirstDay = dayOfWeek(d->firstDayOfYear(year));
+ if (dowFirstDay <= 4 && dayOfIsoWeek < dowFirstDay) {
+ return false;
+ }
+ } else if (year == d->latestValidYear() && isoWeekNumber == weeksInThisYear) {
+ //If lastDayOfYear falls on or after Thursday then lastDayOfYear falls in last week this
+ //year and if wanted dayOfIsoWeek falls after lastDayOfYear then falls in next year
+ //and so in invalid year
+ int dowLastDay = dayOfWeek(d->lastDayOfYear(year));
+ if (dowLastDay >= 4 && dayOfIsoWeek > dowLastDay) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool KCalendarSystem::setDateIsoWeek(QDate &date, int year, int isoWeekNumber, int dayOfIsoWeek) const
+{
+ Q_D(const KCalendarSystem);
+
+ date = QDate();
+
+ if (isValidIsoWeekDate(year, isoWeekNumber, dayOfIsoWeek)) {
+
+ QDate calcDate = d->firstDayOfYear(year);
+ int dowFirstDayOfYear = dayOfWeek(calcDate);
+
+ int daysToAdd = (7 * (isoWeekNumber - 1)) + dayOfIsoWeek;
+
+ if (dowFirstDayOfYear <= 4) {
+ calcDate = calcDate.addDays(daysToAdd - dowFirstDayOfYear);
+ } else {
+ calcDate = calcDate.addDays(7 + daysToAdd - dowFirstDayOfYear);
+ }
+
+ if (isValid(calcDate)) {
+ date = calcDate;
+ return true;
+ }
+ }
+
+ return false;
+}
--
1.7.10.4
More information about the Kde-frameworks-devel
mailing list