diff options
author | Georg Zotti <Georg.Zotti@univie.ac.at> | 2022-02-01 00:38:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-01 00:38:35 +0100 |
commit | 9b1c8a9f868925ba1429b26fd060abca23f6004c (patch) | |
tree | 5c654b8a756dfe60cbdc1f8a147f69eb670ee202 | |
parent | d1f4288c37f159b52097a1b96b7c2e748ab62094 (diff) |
Add Revised Julian Calendar (#2214)
- Fixed the algorithm error from WP
- Add more tests
- SUG: added notes
-rw-r--r-- | guide/plg_calendars.tex | 47 | ||||
-rw-r--r-- | plugins/Calendars/src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | plugins/Calendars/src/Calendar.cpp | 13 | ||||
-rw-r--r-- | plugins/Calendars/src/Calendar.hpp | 3 | ||||
-rw-r--r-- | plugins/Calendars/src/Calendars.cpp | 59 | ||||
-rw-r--r-- | plugins/Calendars/src/Calendars.hpp | 5 | ||||
-rw-r--r-- | plugins/Calendars/src/GregorianCalendar.hpp | 2 | ||||
-rw-r--r-- | plugins/Calendars/src/JulianCalendar.hpp | 2 | ||||
-rw-r--r-- | plugins/Calendars/src/RevisedJulianCalendar.cpp | 124 | ||||
-rw-r--r-- | plugins/Calendars/src/RevisedJulianCalendar.hpp | 61 | ||||
-rw-r--r-- | plugins/Calendars/src/gui/CalendarsDialog.cpp | 10 | ||||
-rw-r--r-- | plugins/Calendars/src/gui/calendarsDialog.ui | 215 | ||||
-rw-r--r-- | plugins/Calendars/src/test/testCalendars.cpp | 340 |
13 files changed, 753 insertions, 130 deletions
diff --git a/guide/plg_calendars.tex b/guide/plg_calendars.tex index 3d92d19715..923d17d780 100644 --- a/guide/plg_calendars.tex +++ b/guide/plg_calendars.tex @@ -66,15 +66,53 @@ dependent on these aspects. \subsection{The Calendars} \subsubsection{Lunisolar European calendars} \begin{description} -\item[Julian] This implementation utilizes historical year counting, - i.e., has no year zero. Years are marked A.D. or B.C., respectively. +\item[Julian] \name[Julius]{Caesar} introduced this calendar, advised + by the Egyptian astronomer \name{Sosigenes}. Every 4th year is a + leap year of 366 instead of 365 days, yielding a mean length of the + year of 365.25 days. + + In contrast to the default calendar display of Stellarium, this + implementation utilizes historical year counting, i.e., has no year + zero. Years are marked A.D. or B.C., respectively. The omission of + year zero makes negative leap years break the simple 4-year + count. Now they are 1~B.C., 5~B.C., 9~B.C.\ etc. However, note that + before 8~A.D.\ leap years are just counted proleptic, but the Romans + did not keep the leap years commanded by \name[Julius]{Caesar} until + \name{Augustus} put things back in order. This means, displayed + dates before 8~A.D.\ may be off by up to 3 days from historical + accounts written by contemporaries. \item[Gregorian] This implementation acts like Stellarium with respect - to year counting and counts negative and positive years, with a year + to year counting and counts signed negative and positive years, with a year zero between them. It shows dates in a \emph{Proleptic Gregorian} calendar for dates before October 15, 1582. Given its improved rules - for leap years, it keeps the season's beginnings closer to the + for leap years which provide a mean length of the year of 365.2425 days, + it keeps the seasons' beginnings closer to the commonly known dates, at least for many more centuries in the past than the Julian calendar commonly used by historians. +\item[Revised Julian Calendar] (also named \textbf{Milankovi\'c + Calendar}) \newFeature{0.22.0} In 1923, the Serbian scientist + \name[Milutin]{Milankovi\'c} (1879--1958) proposed a calendar which + should overcome the then 13-day calendar gap between the Eastern + European Orthodox churches who still adhered to the Julian calendar + and the rest of the world which followed the Gregorian calendar. It + amends the 4-year Julian leap year cycle by omitting century years + except for those where division by 900 leaves a remainder of 200 or + 600. Therefore the mean length of the year is 365.242\={2} days, 24 + seconds less than the Gregorian and within 2 seconds of the correct + length of the mean tropical year. For a synchronisation with the + Gregorian, October 1-13 1923 were omitted. Between March 1600 and + February 2800 the calendar dates are identical to those in the + Gregorian calendar. The calendar was adopted by several but not all + Eastern Orthodox churches, although date of Easter is still computed + according to the Julian calendar\footnote{More details can be found on + \url{https://en.wikipedia.org/wiki/Revised_Julian_calendar}}. + + In historical context giving dates in the Revised Julian calendar + for years before the dates of religious festivals were defined in + the calendar makes no sense. Its idea was to have a continuous + calendar as it was in use at the concile of Nicaea in + A.D.325. Therefore dates before A.D.325 are displayed like in the + traditional Julian calendar. \item[ISO Week] The International Standards Organization describes weeks in the Gregorian calendar from Monday (Day 1) to Sunday (Day 7). Week 1 of each year contains the first Thursday of the @@ -244,6 +282,7 @@ settings for the Calendars plugin -- just make it carefully! show &bool & true\\\midrule show\_julian &bool & true\\ show\_gregorian &bool & true\\ +show\_revised\_julian &bool & true\\ show\_iso &bool & true\\ show\_icelandic &bool & true\\\midrule show\_roman &bool & true\\ diff --git a/plugins/Calendars/src/CMakeLists.txt b/plugins/Calendars/src/CMakeLists.txt index f4e024a89b..bb00bb2b6e 100644 --- a/plugins/Calendars/src/CMakeLists.txt +++ b/plugins/Calendars/src/CMakeLists.txt @@ -19,6 +19,8 @@ SET(Calendars_SRCS ZoroastrianCalendar.cpp JulianCalendar.hpp JulianCalendar.cpp + RevisedJulianCalendar.hpp + RevisedJulianCalendar.cpp RomanCalendar.hpp RomanCalendar.cpp OlympicCalendar.hpp diff --git a/plugins/Calendars/src/Calendar.cpp b/plugins/Calendars/src/Calendar.cpp index 994a276666..217f697ae4 100644 --- a/plugins/Calendars/src/Calendar.cpp +++ b/plugins/Calendars/src/Calendar.cpp @@ -22,6 +22,19 @@ #include "StelApp.hpp" #include "StelCore.hpp" + +QString Calendar::getFormattedDateString(QVector<int> date, QString sep) +{ + QString res; + QVector<int>::const_iterator it; + for (it=date.constBegin(); it!=date.constEnd(); ++it) + { + res.append(QString::number(*it)); + res.append(sep); + } + return res; +} + QString Calendar::getFormattedDateString() const { return getDateStrings().join(' '); diff --git a/plugins/Calendars/src/Calendar.hpp b/plugins/Calendars/src/Calendar.hpp index 66b8c75d58..16e53f38e7 100644 --- a/plugins/Calendars/src/Calendar.hpp +++ b/plugins/Calendars/src/Calendar.hpp @@ -81,6 +81,9 @@ public slots: //! get a formatted complete string for a date. The default implementation just concatenates all strings from getDateStrings() with a space in between. virtual QString getFormattedDateString() const; + //! get a formatted complete string for a date. This implementation just converts and concatenates all ints with sep in between. + static QString getFormattedDateString(QVector<int> date, QString sep=" "); + public: constexpr static const double J2000=2451545.0; constexpr static const double jdEpoch=-1721424.5; diff --git a/plugins/Calendars/src/Calendars.cpp b/plugins/Calendars/src/Calendars.cpp index 6879d169fb..f04f23f55b 100644 --- a/plugins/Calendars/src/Calendars.cpp +++ b/plugins/Calendars/src/Calendars.cpp @@ -33,6 +33,7 @@ #include "CalendarsDialog.hpp" #include "JulianCalendar.hpp" +#include "RevisedJulianCalendar.hpp" #include "GregorianCalendar.hpp" #include "ISOCalendar.hpp" #include "IcelandicCalendar.hpp" @@ -88,6 +89,7 @@ Calendars::Calendars(): toolbarButton(Q_NULLPTR), enabled(true), flagShowJulian(true), + flagShowRevisedJulian(true), flagShowGregorian(true), flagShowISO(true), flagShowIcelandic(true), @@ -192,6 +194,7 @@ void Calendars::init() const double jd=StelApp::getInstance().getCore()->getJD(); calendars.insert("Julian", new JulianCalendar(jd)); + calendars.insert("RevisedJulian", new RevisedJulianCalendar(jd)); calendars.insert("Gregorian", new GregorianCalendar(jd)); calendars.insert("ISO", new ISOCalendar(jd)); calendars.insert("Icelandic", new IcelandicCalendar(jd)); @@ -228,6 +231,7 @@ void Calendars::loadSettings() // Now activate calendar displays if needed. enable( conf->value("Calendars/show", true).toBool()); showJulian( conf->value("Calendars/show_julian", true).toBool()); + showRevisedJulian( conf->value("Calendars/show_revised_julian", true).toBool()); showGregorian( conf->value("Calendars/show_gregorian", true).toBool()); showISO( conf->value("Calendars/show_iso", true).toBool()); showIcelandic( conf->value("Calendars/show_icelandic", true).toBool()); @@ -278,28 +282,29 @@ void Calendars::draw(StelCore* core) oss << "<table>"; // Select the drawable calendars from GUI or settings. if (calendars.count()==0) return; - if (flagShowJulian) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Julian", "calendar"), getCal("Julian")->getFormattedDateString()); - if (flagShowGregorian) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Gregorian", "calendar"), getCal("Gregorian")->getFormattedDateString()); - if (flagShowISO) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("ISO week", "calendar"), getCal("ISO")->getFormattedDateString()); - if (flagShowIcelandic) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Icelandic", "calendar"), getCal("Icelandic")->getFormattedDateString()); - if (flagShowRoman) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Roman", "calendar"), getCal("Roman")->getFormattedDateString()); - if (flagShowOlympic) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Olympic", "calendar"), getCal("Olympic")->getFormattedDateString()); - if (flagShowEgyptian) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Egyptian", "calendar"), getCal("Egyptian")->getFormattedDateString()); - if (flagShowArmenian) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Armenian", "calendar"), getCal("Armenian")->getFormattedDateString()); - if (flagShowZoroastrian) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Zoroastrian", "calendar"), getCal("Zoroastrian")->getFormattedDateString()); - if (flagShowCoptic) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Coptic", "calendar"), getCal("Coptic")->getFormattedDateString()); - if (flagShowEthiopic) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Ethiopic", "calendar"), getCal("Ethiopic")->getFormattedDateString()); - if (flagShowFrenchArithmetic) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("French Rev. (Arithm.)", "calendar"), getCal("FrenchArithmetic")->getFormattedDateString()); - if (flagShowIslamic) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Islamic", "calendar"), getCal("Islamic")->getFormattedDateString()); - if (flagShowHebrew) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Hebrew", "calendar"), getCal("Hebrew")->getFormattedDateString()); - if (flagShowPersianArithmetic) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Persian (Arithm.)", "calendar"), getCal("PersianArithmetic")->getFormattedDateString()); - if (flagShowOldHinduSolar) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Old Hindu Solar", "calendar"), getCal("OldHinduSolar")->getFormattedDateString()); - if (flagShowOldHinduLunar) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Old Hindu Lunisolar", "calendar"), getCal("OldHinduLunar")->getFormattedDateString()); - if (flagShowMayaLongCount) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Maya Long Count", "calendar"), getCal("MayaLongCount")->getFormattedDateString()); - if (flagShowMayaHaab) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Maya Haab", "calendar"), getCal("MayaHaab")->getFormattedDateString()); - if (flagShowMayaTzolkin) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Maya Tzolkin", "calendar"), getCal("MayaTzolkin")->getFormattedDateString()); - if (flagShowAztecXihuitl) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Aztec Xihuitl", "calendar"), getCal("AztecXihuitl")->getFormattedDateString()); - if (flagShowAztecTonalpohualli) oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Aztec Tonalpohualli", "calendar"), getCal("AztecTonalpohualli")->getFormattedDateString()); + if (flagShowJulian) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Julian", "calendar"), getCal("Julian")->getFormattedDateString()); + if (flagShowGregorian) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Gregorian", "calendar"), getCal("Gregorian")->getFormattedDateString()); + if (flagShowRevisedJulian) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Revised Julian", "calendar"), getCal("RevisedJulian")->getFormattedDateString()); + if (flagShowISO) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("ISO week", "calendar"), getCal("ISO")->getFormattedDateString()); + if (flagShowIcelandic) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Icelandic", "calendar"), getCal("Icelandic")->getFormattedDateString()); + if (flagShowRoman) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Roman", "calendar"), getCal("Roman")->getFormattedDateString()); + if (flagShowOlympic) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Olympic", "calendar"), getCal("Olympic")->getFormattedDateString()); + if (flagShowEgyptian) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Egyptian", "calendar"), getCal("Egyptian")->getFormattedDateString()); + if (flagShowArmenian) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Armenian", "calendar"), getCal("Armenian")->getFormattedDateString()); + if (flagShowZoroastrian) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Zoroastrian", "calendar"), getCal("Zoroastrian")->getFormattedDateString()); + if (flagShowCoptic) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Coptic", "calendar"), getCal("Coptic")->getFormattedDateString()); + if (flagShowEthiopic) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Ethiopic", "calendar"), getCal("Ethiopic")->getFormattedDateString()); + if (flagShowFrenchArithmetic) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("French Rev. (Arithm.)", "calendar"), getCal("FrenchArithmetic")->getFormattedDateString()); + if (flagShowIslamic) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Islamic", "calendar"), getCal("Islamic")->getFormattedDateString()); + if (flagShowHebrew) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Hebrew", "calendar"), getCal("Hebrew")->getFormattedDateString()); + if (flagShowPersianArithmetic) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Persian (Arithm.)", "calendar"), getCal("PersianArithmetic")->getFormattedDateString()); + if (flagShowOldHinduSolar) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Old Hindu Solar", "calendar"), getCal("OldHinduSolar")->getFormattedDateString()); + if (flagShowOldHinduLunar) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Old Hindu Lunisolar", "calendar"), getCal("OldHinduLunar")->getFormattedDateString()); + if (flagShowMayaLongCount) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Maya Long Count", "calendar"), getCal("MayaLongCount")->getFormattedDateString()); + if (flagShowMayaHaab) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Maya Haab", "calendar"), getCal("MayaHaab")->getFormattedDateString()); + if (flagShowMayaTzolkin) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Maya Tzolkin", "calendar"), getCal("MayaTzolkin")->getFormattedDateString()); + if (flagShowAztecXihuitl) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Aztec Xihuitl", "calendar"), getCal("AztecXihuitl")->getFormattedDateString()); + if (flagShowAztecTonalpohualli) oss << QString("<tr><td>%1 </td><td>%2</td></tr>").arg(qc_("Aztec Tonalpohualli", "calendar"), getCal("AztecTonalpohualli")->getFormattedDateString()); if (flagShowBalinese) { oss << QString("<tr><td>%1</td><td>%2</td></tr>").arg(qc_("Balinese Pawukon", "calendar"), static_cast<BalinesePawukonCalendar*>(getCal("Balinese"))->getFormattedDateString1to5()); oss << QString("<tr><td> </td><td>%1</td></tr>").arg(static_cast<BalinesePawukonCalendar*>(getCal("Balinese"))->getFormattedDateString6to10()); @@ -362,6 +367,16 @@ void Calendars::showJulian(bool b) emit showJulianChanged(b); } } +bool Calendars::isRevisedJulianDisplayed() const { return flagShowRevisedJulian;} +void Calendars::showRevisedJulian(bool b) +{ + if (b!=flagShowRevisedJulian) + { + flagShowRevisedJulian=b; + conf->setValue("Calendars/show_revised_julian", b); + emit showJulianChanged(b); + } +} bool Calendars::isGregorianDisplayed() const { return flagShowGregorian;} void Calendars::showGregorian(bool b) { diff --git a/plugins/Calendars/src/Calendars.hpp b/plugins/Calendars/src/Calendars.hpp index b81e1f8f9c..235e66a313 100644 --- a/plugins/Calendars/src/Calendars.hpp +++ b/plugins/Calendars/src/Calendars.hpp @@ -37,6 +37,7 @@ class Calendars : public StelModule Q_OBJECT Q_PROPERTY(bool enabled READ isEnabled WRITE enable NOTIFY enabledChanged) Q_PROPERTY(bool flagShowJulian READ isJulianDisplayed WRITE showJulian NOTIFY showJulianChanged) + Q_PROPERTY(bool flagShowRevisedJulian READ isRevisedJulianDisplayed WRITE showRevisedJulian NOTIFY showRevisedJulianChanged) Q_PROPERTY(bool flagShowGregorian READ isGregorianDisplayed WRITE showGregorian NOTIFY showGregorianChanged) Q_PROPERTY(bool flagShowISO READ isISODisplayed WRITE showISO NOTIFY showISOChanged) Q_PROPERTY(bool flagShowIcelandic READ isIcelandicDisplayed WRITE showIcelandic NOTIFY showIcelandicChanged) @@ -101,6 +102,7 @@ signals: void enabledChanged(bool b); void showJulianChanged(bool b); + void showRevisedJulianChanged(bool b); void showGregorianChanged(bool b); void showISOChanged(bool b); void showIcelandicChanged(bool b); @@ -133,6 +135,8 @@ public slots: void enable(bool b); bool isJulianDisplayed() const; //!< display Julian Calendar? void showJulian(bool b); //!< activate display of Julian Calendar + bool isRevisedJulianDisplayed() const; //!< display Revised Julian Calendar? + void showRevisedJulian(bool b); //!< activate display of Revised Julian Calendar bool isGregorianDisplayed() const; //!< display Gregorian Calendar? void showGregorian(bool b); //!< activate display of Gregorian Calendar bool isISODisplayed() const; //!< display ISO Calendar? @@ -198,6 +202,7 @@ private: // StelProperties: bool enabled; bool flagShowJulian; + bool flagShowRevisedJulian; bool flagShowGregorian; bool flagShowISO; bool flagShowIcelandic; diff --git a/plugins/Calendars/src/GregorianCalendar.hpp b/plugins/Calendars/src/GregorianCalendar.hpp index 97b6182412..0c827ae55e 100644 --- a/plugins/Calendars/src/GregorianCalendar.hpp +++ b/plugins/Calendars/src/GregorianCalendar.hpp @@ -56,7 +56,7 @@ public: //! returns true for leap years static bool isLeap(int year); - constexpr static const int gregorianEpoch=1; //! RD of January 1, AD1. + constexpr static const int gregorianEpoch=1; //! RD of January 1, AD1 (greg). //! auxiliary functions from CC.UE ch2.5 //! Return R.D. of date in the Gregorian calendar. static int fixedFromGregorian(QVector<int> gregorian); diff --git a/plugins/Calendars/src/JulianCalendar.hpp b/plugins/Calendars/src/JulianCalendar.hpp index d14f885b27..cb67172b58 100644 --- a/plugins/Calendars/src/JulianCalendar.hpp +++ b/plugins/Calendars/src/JulianCalendar.hpp @@ -68,7 +68,7 @@ public: //! find date in the Julian calendar from RD number (may be used in other calendars!) static QVector<int> julianFromFixed(int rd); - constexpr static const int julianEpoch=-1; //! RD of January 1, AD1. + constexpr static const int julianEpoch=-1; //! RD of January 1, AD1 (jul.). protected: static QMap<int, QString> weekDayNames; diff --git a/plugins/Calendars/src/RevisedJulianCalendar.cpp b/plugins/Calendars/src/RevisedJulianCalendar.cpp new file mode 100644 index 0000000000..c00d924cf5 --- /dev/null +++ b/plugins/Calendars/src/RevisedJulianCalendar.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2022 Georg Zotti + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. + */ + +#include "StelTranslator.hpp" +#include "RevisedJulianCalendar.hpp" +#include "StelUtils.hpp" +#include "StelApp.hpp" +#include "StelCore.hpp" + +RevisedJulianCalendar::RevisedJulianCalendar(double jd): JulianCalendar(jd) +{ +} + +// Set a calendar date from the Julian day number +void RevisedJulianCalendar::setJD(double JD) +{ + this->JD=JD; + + int rd=fixedFromJD(JD, true); + parts=revisedJulianFromFixed(rd); + + emit partsChanged(parts); +} + +// set date from a vector of calendar date elements sorted from the largest to the smallest. +// Year-Month[1...12]-Day[1...31] +// Time is not changed! +void RevisedJulianCalendar::setDate(QVector<int> parts) +{ + //qDebug() << "RevisedJulianCalendar::setDate:" << parts; + this->parts=parts; + // For the Julian calendar, we really have no year 0 in this plugin. + Q_ASSERT(parts.at(0) != 0); + + double rd=fixedFromRevisedJulian(parts); + // restore time from JD! + double frac=StelUtils::fmodpos(JD+0.5+StelApp::getInstance().getCore()->getUTCOffset(JD)/24., 1.); + JD=jdFromFixed(rd+frac, true); + + emit jdChanged(JD); +} + +// returns true for leap years. The algorithm only works correctly for positive years! +// But we make the switchover in 325. +bool RevisedJulianCalendar::isLeap(int year) +{ + if (year<325) + return JulianCalendar::isLeap(year); + + bool leap= (StelUtils::imod(year, 4) == 0); + if (leap && (StelUtils::imod(year, 100) == 0)) + { + int century=StelUtils::imod(year, 900); + leap=(century==200) || (century==600); + } + return leap; +} + +int RevisedJulianCalendar::fixedFromRevisedJulian(QVector<int> revisedJulian) +{ + const int year=revisedJulian.at(0); + const int month=revisedJulian.at(1); + const int day=revisedJulian.at(2); + // Year BC make no sense here! Don't bother dealing with the leap years... + // But note that the calendars were parallel in 325 (Nicaea) + if (year<325) + return JulianCalendar::fixedFromJulian(revisedJulian); + + const int priorYear=year-1; + int fixedDay=revisedJulianEpoch+365*priorYear+StelUtils::intFloorDiv(priorYear,4)+StelUtils::intFloorDiv(367*month-362, 12)+day-1; + // If month is after February then subtract 1 day for a leap year or subtract 2 days for a common year: + if (month>2) + fixedDay -= isLeap(year) ? 1 : 2; + // Finally subtract a day for each prior century year (most of which are non-leap) and then add back in the number of prior century leap years: + int priorCenturies=StelUtils::intFloorDiv(priorYear, 100); + fixedDay += -priorCenturies + StelUtils::intFloorDiv(2*priorCenturies+6, 9); + return fixedDay; +} + +QVector<int> RevisedJulianCalendar::revisedJulianFromFixed(int rd) +{ + static const int rd325=fixedFromJulian({325, 6, 30}); + if (rd<rd325) + return JulianCalendar::julianFromFixed(rd); + const int days = rd-revisedJulianEpoch+1; + const int priorCenturies = StelUtils::intFloorDiv(days, 36524); // n100 in Gregorian algorithm + int remainingDays = days-36524*priorCenturies-StelUtils::intFloorDiv(2*priorCenturies+6, 9); // + const int priorSubcycles = StelUtils::intFloorDiv(remainingDays, 1461); // n4 in Gregorian algorithm + remainingDays = StelUtils::imod(remainingDays,1461); // d3 + const int priorSubcycleYears = StelUtils::intFloorDiv(remainingDays, 365); // n1 + int year = 100 * priorCenturies + 4 * priorSubcycles + priorSubcycleYears; + // Add a correction which was omitted in Wikipedia! + if ( !((priorSubcycleYears==4) || (priorCenturies==2))) + year+=1; + + remainingDays = StelUtils::imod(remainingDays, 365); + if (remainingDays == 0) + { + //This is either the 365th day of a common year, or the 365th or 366th day of a leap year. Either way, we have to decrement the year because we went one year too far: + year--; + remainingDays = isLeap(year) && (priorSubcycles==0) ? 366 : 365; + } + int priorDays = remainingDays - 1; + int correction = isLeap(year) ? 1 : 0; + correction = (priorDays < (31+28+correction)) ? 0 : 2 - correction; + int month = StelUtils::intFloorDiv((12 * (priorDays + correction) + 373) , 367); + const int day=rd-fixedFromRevisedJulian({year, month, 1})+1; + return {year, month, day}; +} diff --git a/plugins/Calendars/src/RevisedJulianCalendar.hpp b/plugins/Calendars/src/RevisedJulianCalendar.hpp new file mode 100644 index 0000000000..9b43ba1306 --- /dev/null +++ b/plugins/Calendars/src/RevisedJulianCalendar.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2022 Georg Zotti + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. + */ + +#ifndef REVISEDJULIANCALENDAR_HPP +#define REVISEDJULIANCALENDAR_HPP + +#include "JulianCalendar.hpp" + +//! The Orthodox Church worked out a Revised Julian Calendar in 1923 to overcome the 13-day gap between their traditional Julian and the rest of the world which is using the Gregorian. +//! In this calendar, only centuries where division by 900 yields 200 or 600 are leap years. +//! Dates from March 1st, 1600 to February 28th, 2800, go in sync with the Gregorian calendar. +//! The algorithm implemented here was taken from https://en.wikipedia.org/wiki/Revised_Julian_calendar in January 2022 (with a necessary fix discovered during implementation) +//! @note Behaviour of this calendar for dates BC is not documented. +//! In the first century, dates are 2 days away from the Julian. +//! Around the Nicaean concile (AD325) this calendar provides the same dates as the Julian, therefore we make the switchover in AD325, and forward all earlier dates to the Julian calendar. + +class RevisedJulianCalendar : public JulianCalendar +{ + Q_OBJECT + +public: + RevisedJulianCalendar(double jd); + virtual ~RevisedJulianCalendar() Q_DECL_OVERRIDE {} + +public slots: + //! Set a calendar date from the Julian day number + virtual void setJD(double JD) Q_DECL_OVERRIDE; + + //! set date from a vector of calendar date elements sorted from the largest to the smallest. + //! Year-Month[1...12]-Day[1...31] + virtual void setDate(QVector<int> parts) Q_DECL_OVERRIDE; + +public: + //! returns true for leap years. We handle years prior to 325 like in the regular Julian calendar. + static bool isLeap(int year); + + //! find RD number for date in the Revised Julian calendar. Dates before AD325 are handled as dates in the regular Julian calendar. + static int fixedFromRevisedJulian(QVector<int> revisedJulian); + //! find date in the Revised Julian calendar from RD number. If date is earlier than AD325, + //! the returned date is in the standard Julian Calendar. + static QVector<int> revisedJulianFromFixed(int rd); + + constexpr static const int revisedJulianEpoch=1; //! RD of January 1, AD1. +}; + +#endif diff --git a/plugins/Calendars/src/gui/CalendarsDialog.cpp b/plugins/Calendars/src/gui/CalendarsDialog.cpp index 1bbaa6e4db..eb6be4bbeb 100644 --- a/plugins/Calendars/src/gui/CalendarsDialog.cpp +++ b/plugins/Calendars/src/gui/CalendarsDialog.cpp @@ -77,11 +77,17 @@ void CalendarsDialog::createDialogContent() connect(ui->restoreDefaultsButton, SIGNAL(clicked()), this, SLOT(resetCalendarsSettings())); setAboutHtml(); - // DISABLE Chinese for now, TBD! +#ifdef STELLARIUM_RELEASE_BUILD + ui->labelRDvalue->hide(); + ui->labelRD->hide(); + // DISABLE Chinese etc for now, TBD! ui->chineseCheckBox->hide(); ui->tabs->removeTab(2); ui->newHinduLunarCheckBox->hide(); ui->newHinduSolarCheckBox->hide(); +#else + connect(cal->getCal("Julian"), &JulianCalendar::jdChanged, this, [=](double jd){ui->labelRDvalue->setText(QString::number(Calendar::fixedFromJD(jd)));}); +#endif // MAKE SURE to connect each calendar's partsChanged to a respective populate... method here. connect(cal->getCal("Julian"), SIGNAL(partsChanged(QVector<int>)), this, SLOT(populateJulianParts(QVector<int>))); @@ -95,6 +101,7 @@ void CalendarsDialog::createDialogContent() //connect(cal->getCal("Chinese"), SIGNAL(partsChanged(QVector<int>)), this, SLOT(populateChineseParts(QVector<int>))); connectBoolProperty(ui->julianCheckBox, "Calendars.flagShowJulian"); + connectBoolProperty(ui->revisedJulianCheckBox, "Calendars.flagShowRevisedJulian"); connectBoolProperty(ui->gregorianCheckBox, "Calendars.flagShowGregorian"); connectBoolProperty(ui->isoCheckBox, "Calendars.flagShowISO"); connectBoolProperty(ui->romanCheckBox, "Calendars.flagShowRoman"); @@ -167,6 +174,7 @@ void CalendarsDialog::setAboutHtml(void) html += "<p>" + q_("The Calendars plugin provides an interface to various calendars used around the world.") + "</p>"; html += "<ul><li>" + q_("Julian Calendar") + "</li>"; html += "<li>" + q_("Gregorian Calendar") + "</li>"; + html += "<li>" + q_("Revised Julian Calendar (Milanković)") + "</li>"; html += "<li>" + q_("ISO Weeks") + "</li>"; html += "<li>" + q_("Icelandic calendar") + "</li>"; html += "<li>" + q_("Roman (Julian) calendar") + "</li>"; diff --git a/plugins/Calendars/src/gui/calendarsDialog.ui b/plugins/Calendars/src/gui/calendarsDialog.ui index 0ee3897323..d118e5cc7a 100644 --- a/plugins/Calendars/src/gui/calendarsDialog.ui +++ b/plugins/Calendars/src/gui/calendarsDialog.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>558</width> - <height>405</height> + <height>419</height> </rect> </property> <property name="windowTitle"> @@ -154,13 +154,6 @@ </property> </widget> </item> - <item row="1" column="0"> - <widget class="QCheckBox" name="romanCheckBox"> - <property name="text"> - <string comment="calendar">Roman</string> - </property> - </widget> - </item> <item row="10" column="0"> <widget class="QCheckBox" name="balineseCheckBox"> <property name="text"> @@ -175,13 +168,6 @@ </property> </widget> </item> - <item row="0" column="2"> - <widget class="QCheckBox" name="isoCheckBox"> - <property name="text"> - <string comment="calendar">ISO Week</string> - </property> - </widget> - </item> <item row="9" column="1"> <widget class="QCheckBox" name="newHinduLunarCheckBox"> <property name="text"> @@ -217,13 +203,6 @@ </property> </widget> </item> - <item row="2" column="2"> - <widget class="QCheckBox" name="zoroastrianCheckBox"> - <property name="text"> - <string comment="calendar">Zoroastrian</string> - </property> - </widget> - </item> <item row="9" column="0"> <widget class="QCheckBox" name="newHinduSolarCheckBox"> <property name="text"> @@ -287,13 +266,6 @@ </property> </widget> </item> - <item row="1" column="2"> - <widget class="QCheckBox" name="icelandicCheckBox"> - <property name="text"> - <string comment="calendar">Icelandic</string> - </property> - </widget> - </item> <item row="6" column="0"> <widget class="QCheckBox" name="mayaLCCheckBox"> <property name="text"> @@ -329,6 +301,41 @@ </property> </widget> </item> + <item row="3" column="2"> + <widget class="QCheckBox" name="zoroastrianCheckBox"> + <property name="text"> + <string comment="calendar">Zoroastrian</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QCheckBox" name="icelandicCheckBox"> + <property name="text"> + <string comment="calendar">Icelandic</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QCheckBox" name="isoCheckBox"> + <property name="text"> + <string comment="calendar">ISO Week</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QCheckBox" name="romanCheckBox"> + <property name="text"> + <string comment="calendar">Roman</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="revisedJulianCheckBox"> + <property name="text"> + <string>Revised Julian</string> + </property> + </widget> + </item> </layout> </item> <item> @@ -370,21 +377,18 @@ <layout class="QVBoxLayout" name="lunisolarVerticalLayout"> <item> <layout class="QGridLayout" name="lunisolarGridLayout"> - <item row="1" column="4"> - <widget class="QLineEdit" name="julianWeekdayLineEdit"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="acceptDrops"> - <bool>false</bool> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <item row="0" column="1"> + <widget class="QLabel" name="labelYear"> + <property name="text"> + <string>Year</string> </property> </widget> </item> - <item row="2" column="1"> - <widget class="QSpinBox" name="gregorianYearSpinBox"> + <item row="1" column="1"> + <widget class="QSpinBox" name="julianYearSpinBox"> + <property name="toolTip"> + <string>Negative years here mark years B.C.</string> + </property> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> @@ -406,8 +410,8 @@ </property> </widget> </item> - <item row="1" column="2"> - <widget class="QSpinBox" name="julianMonthSpinBox"> + <item row="3" column="2"> + <widget class="QSpinBox" name="isoWeekSpinBox"> <property name="wrapping"> <bool>true</bool> </property> @@ -418,20 +422,7 @@ <number>0</number> </property> <property name="maximum"> - <number>13</number> - </property> - </widget> - </item> - <item row="2" column="4"> - <widget class="QLineEdit" name="gregorianWeekdayLineEdit"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="acceptDrops"> - <bool>false</bool> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + <number>54</number> </property> </widget> </item> @@ -449,8 +440,8 @@ </property> </widget> </item> - <item row="2" column="3"> - <widget class="QSpinBox" name="gregorianDaySpinBox"> + <item row="2" column="2"> + <widget class="QSpinBox" name="gregorianMonthSpinBox"> <property name="wrapping"> <bool>true</bool> </property> @@ -461,23 +452,36 @@ <number>0</number> </property> <property name="maximum"> - <number>32</number> + <number>13</number> </property> </widget> </item> - <item row="1" column="3"> - <widget class="QSpinBox" name="julianDaySpinBox"> - <property name="wrapping"> - <bool>true</bool> - </property> + <item row="2" column="1"> + <widget class="QSpinBox" name="gregorianYearSpinBox"> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> <property name="minimum"> - <number>0</number> + <number>-100000</number> </property> <property name="maximum"> - <number>32</number> + <number>100000</number> + </property> + <property name="value"> + <number>2000</number> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QLineEdit" name="julianWeekdayLineEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="acceptDrops"> + <bool>false</bool> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> </widget> </item> @@ -488,8 +492,8 @@ </property> </widget> </item> - <item row="3" column="2"> - <widget class="QSpinBox" name="isoWeekSpinBox"> + <item row="2" column="3"> + <widget class="QSpinBox" name="gregorianDaySpinBox"> <property name="wrapping"> <bool>true</bool> </property> @@ -500,12 +504,28 @@ <number>0</number> </property> <property name="maximum"> - <number>54</number> + <number>32</number> </property> </widget> </item> - <item row="2" column="2"> - <widget class="QSpinBox" name="gregorianMonthSpinBox"> + <item row="3" column="3"> + <widget class="QSpinBox" name="isoDaySpinBox"> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>8</number> + </property> + <property name="value"> + <number>1</number> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QSpinBox" name="julianMonthSpinBox"> <property name="wrapping"> <bool>true</bool> </property> @@ -534,34 +554,24 @@ </property> </widget> </item> - <item row="1" column="1"> - <widget class="QSpinBox" name="julianYearSpinBox"> - <property name="toolTip"> - <string>Negative years here mark years B.C.</string> + <item row="2" column="4"> + <widget class="QLineEdit" name="gregorianWeekdayLineEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="acceptDrops"> + <bool>false</bool> </property> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> - <property name="minimum"> - <number>-100000</number> - </property> - <property name="maximum"> - <number>100000</number> - </property> - <property name="value"> - <number>2000</number> - </property> </widget> </item> - <item row="0" column="1"> - <widget class="QLabel" name="labelYear"> - <property name="text"> - <string>Year</string> + <item row="1" column="3"> + <widget class="QSpinBox" name="julianDaySpinBox"> + <property name="wrapping"> + <bool>true</bool> </property> - </widget> - </item> - <item row="3" column="3"> - <widget class="QSpinBox" name="isoDaySpinBox"> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> @@ -569,10 +579,7 @@ <number>0</number> </property> <property name="maximum"> - <number>8</number> - </property> - <property name="value"> - <number>1</number> + <number>32</number> </property> </widget> </item> @@ -589,6 +596,20 @@ </property> </widget> </item> + <item row="4" column="0"> + <widget class="QLabel" name="labelRD"> + <property name="text"> + <string>Rata Die</string> + </property> + </widget> + </item> + <item row="4" column="4"> + <widget class="QLabel" name="labelRDvalue"> + <property name="text"> + <string>RD number</string> + </property> + </widget> + </item> </layout> </item> <item> diff --git a/plugins/Calendars/src/test/testCalendars.cpp b/plugins/Calendars/src/test/testCalendars.cpp index ce69455af2..a77142a287 100644 --- a/plugins/Calendars/src/test/testCalendars.cpp +++ b/plugins/Calendars/src/test/testCalendars.cpp @@ -28,6 +28,10 @@ #include "StelUtils.hpp" #include "../Calendar.hpp" #include "../JulianCalendar.hpp" +#include "../RevisedJulianCalendar.hpp" +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) +#include <QCalendar> +#endif #include "../GregorianCalendar.hpp" #include "../ISOCalendar.hpp" #include "../IcelandicCalendar.hpp" @@ -81,14 +85,15 @@ void TestCalendars::testBasics() QVERIFY2(Calendar::modInterval(5, 1, 2)==1, qPrintable(QString("modInterval(5, 1, 2)=%1").arg(QString::number(Calendar::modInterval(5, 1, 2))))); QVERIFY2(Calendar::modInterval(6, 1, 2)==1, qPrintable(QString("modInterval(6, 1, 2)=%1").arg(QString::number(Calendar::modInterval(6, 1, 2))))); // Critically important: modinterval(., 1, n)=amod(., n-1). n is NOT the maximum possible return value! - QVERIFY2(Calendar::modInterval(42, 1, 7)==StelUtils::amod(42, 6), qPrintable(QString("modInterval(42, 1, 6)=%1 vs amod(42, 6)=%2").arg(QString::number(Calendar::modInterval(5, 1, 2))).arg(QString::number(StelUtils::amod(42, 6))))); - QVERIFY2(Calendar::modInterval(43, 1, 7)==StelUtils::amod(43, 6), qPrintable(QString("modInterval(43, 1, 6)=%1 vs amod(43, 6)=%2").arg(QString::number(Calendar::modInterval(6, 1, 2))).arg(QString::number(StelUtils::amod(43, 6))))); + QVERIFY2(Calendar::modInterval(42, 1, 7)==StelUtils::amod(42, 6), qPrintable(QString("modInterval(42, 1, 6)=%1 vs amod(42, 6)=%2").arg(QString::number(Calendar::modInterval(5, 1, 2)), QString::number(StelUtils::amod(42, 6))))); + QVERIFY2(Calendar::modInterval(43, 1, 7)==StelUtils::amod(43, 6), qPrintable(QString("modInterval(43, 1, 6)=%1 vs amod(43, 6)=%2").arg(QString::number(Calendar::modInterval(6, 1, 2)), QString::number(StelUtils::amod(43, 6))))); QVERIFY(StelUtils::intFloorDiv(8, 2)==4); QVERIFY(StelUtils::intFloorDiv(8, 3)==2); QVERIFY(StelUtils::intFloorDiv(-8, 3)==-3); QVERIFY(StelUtils::intFloorDiv(-8, -2)==4); QVERIFY(StelUtils::intFloorDiv(-8, 2)==-4); QVERIFY(StelUtils::intFloorDiv(8, -2)==-4); + QVERIFY(StelUtils::imod(-1, 100)==99); } void TestCalendars::testEuropean() @@ -99,6 +104,333 @@ void TestCalendars::testEuropean() QVERIFY(JulianCalendar::fixedFromJulian({1, 1, 1})==JulianCalendar::julianEpoch); QVERIFY(JulianCalendar::fixedFromJulian({1, 1, 1})==GregorianCalendar::fixedFromGregorian({0, JulianCalendar::december, 30})); +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + // RevisedJulianCalendar should behave identical to Qt's MilankovicCalendar. + QCalendar mil(QCalendar::System::Milankovic); + for (int year=400; year<10001; year+=100) + QVERIFY(RevisedJulianCalendar::isLeap(year)==mil.isLeapYear(year)); +#endif + QVERIFY(RevisedJulianCalendar::isLeap( 400)==false); + QVERIFY(RevisedJulianCalendar::isLeap( 500)==false); + QVERIFY(RevisedJulianCalendar::isLeap( 600)==true); + QVERIFY(RevisedJulianCalendar::isLeap( 700)==false); + QVERIFY(RevisedJulianCalendar::isLeap( 800)==false); + QVERIFY(RevisedJulianCalendar::isLeap( 900)==false); + QVERIFY(RevisedJulianCalendar::isLeap(1000)==false); + QVERIFY(RevisedJulianCalendar::isLeap(1100)==true); + QVERIFY(RevisedJulianCalendar::isLeap(1200)==false); + QVERIFY(RevisedJulianCalendar::isLeap(1300)==false); + QVERIFY(RevisedJulianCalendar::isLeap(1400)==false); + QVERIFY(RevisedJulianCalendar::isLeap(1500)==true); + QVERIFY(RevisedJulianCalendar::isLeap(1600)==false); + QVERIFY(RevisedJulianCalendar::isLeap(1700)==false); + QVERIFY(RevisedJulianCalendar::isLeap(1800)==false); + QVERIFY(RevisedJulianCalendar::isLeap(1900)==false); + QVERIFY(RevisedJulianCalendar::isLeap(2000)==true); + QVERIFY(RevisedJulianCalendar::isLeap(2100)==false); + QVERIFY(RevisedJulianCalendar::isLeap(2200)==false); + QVERIFY(RevisedJulianCalendar::isLeap(2300)==false); + QVERIFY(RevisedJulianCalendar::isLeap(2400)==true); + QVERIFY(RevisedJulianCalendar::isLeap(2500)==false); + QVERIFY(RevisedJulianCalendar::isLeap(2600)==false); + QVERIFY(RevisedJulianCalendar::isLeap(2700)==false); + QVERIFY(RevisedJulianCalendar::isLeap(2800)==false); + QVERIFY(RevisedJulianCalendar::isLeap(2900)==true); + QVERIFY(RevisedJulianCalendar::isLeap(3000)==false); + QVERIFY(RevisedJulianCalendar::isLeap(3100)==false); + QVERIFY(RevisedJulianCalendar::isLeap(3200)==false); + QVERIFY(RevisedJulianCalendar::isLeap(3300)==true); + QVERIFY(RevisedJulianCalendar::isLeap(3400)==false); + QVERIFY(RevisedJulianCalendar::isLeap(3500)==false); + QVERIFY(RevisedJulianCalendar::isLeap(3600)==false); + QVERIFY(RevisedJulianCalendar::isLeap(3700)==false); + QVERIFY(RevisedJulianCalendar::isLeap(3800)==true); + QVERIFY(RevisedJulianCalendar::isLeap(3900)==false); + QVERIFY(RevisedJulianCalendar::isLeap(4000)==false); + QVERIFY(RevisedJulianCalendar::revisedJulianEpoch==Calendar::fixedFromJD(1721425.5, false)); + QVERIFY2(qFuzzyCompare(RevisedJulianCalendar::fixedFromRevisedJulian({2000, 1, 1}), 730120.5 - 0.5), // Subtract half-day. + qPrintable(QString("fixed from Revised Julian 1.1.2000: %1 (expected %2)").arg(RevisedJulianCalendar::fixedFromRevisedJulian({2000, 1, 1})).arg(730120.5-0.5, 8, 'f'))); + + // Test simple date reversion for all dates 1..28.month.year in sensible range. + for (int y=325; y<10799; y++) + for (int m=1; m<=12; ++m) + for (int d=1; d<29; d++) + { + QVector<int> date={y, m, d}; + QVERIFY2(RevisedJulianCalendar::revisedJulianFromFixed(RevisedJulianCalendar::fixedFromRevisedJulian(date)) == date, + qPrintable(QString("Problem with date %1").arg(Calendar::getFormattedDateString(date, ":")))); + } + + // Make sure to get the transition right. + for (int y=325; y<400; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==JulianCalendar::fixedFromJulian({y, m, 1})); + // Rest of table from https://en.wikipedia.org/wiki/Revised_Julian_calendar. Note that the arithmetic result is reversed from the list. + for (int y=325; y<400; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})+1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({400, m, 1})==GregorianCalendar::fixedFromGregorian({400, m, 1})+1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({400, m, 1})==GregorianCalendar::fixedFromGregorian({400, m, 1})); + for (int y=401; y<600; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({600, m, 1})==GregorianCalendar::fixedFromGregorian({600, m, 1})); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({600, m, 1})==GregorianCalendar::fixedFromGregorian({600, m, 1})+1); + for (int y=601; y<800; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})+1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({800, m, 1})==GregorianCalendar::fixedFromGregorian({800, m, 1})+1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({800, m, 1})==GregorianCalendar::fixedFromGregorian({800, m, 1})); + for (int y=801; y<1100; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({1100, m, 1})==GregorianCalendar::fixedFromGregorian({1100, m, 1})); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({1100, m, 1})==GregorianCalendar::fixedFromGregorian({1100, m, 1})+1); + for (int y=1101; y<1200; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})+1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({1200, m, 1})==GregorianCalendar::fixedFromGregorian({1200, m, 1})+1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({1200, m, 1})==GregorianCalendar::fixedFromGregorian({1200, m, 1})); + for (int y=1201; y<1500; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({1500, m, 1})==GregorianCalendar::fixedFromGregorian({1500, m, 1})); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({1500, m, 1})==GregorianCalendar::fixedFromGregorian({1500, m, 1})+1); + for (int y=1501; y<1600; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})+1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({1600, m, 1})==GregorianCalendar::fixedFromGregorian({1600, m, 1})+1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({1600, m, 1})==GregorianCalendar::fixedFromGregorian({1600, m, 1})); + for (int y=1601; y<2800; y++) + for (int m=1; m<=12; ++m) + { + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})); + for (int d=1; d<29; d++) + { + QVector<int> date={y, m, d}; + QVERIFY(RevisedJulianCalendar::revisedJulianFromFixed(GregorianCalendar::fixedFromGregorian(date)) == date); + } + } + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({2800, m, 1})==GregorianCalendar::fixedFromGregorian({2800, m, 1})); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({2800, m, 1})==GregorianCalendar::fixedFromGregorian({2800, m, 1})-1); + for (int y=2801; y<2900; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({2900, m, 1})==GregorianCalendar::fixedFromGregorian({2900, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({2900, m, 1})==GregorianCalendar::fixedFromGregorian({2900, m, 1})); + for (int y=2901; y<3200; y++) + for (int m=1; m<=12; ++m) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({3200, m, 1})==GregorianCalendar::fixedFromGregorian({3200, m, 1})); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({3300, m, 1})==GregorianCalendar::fixedFromGregorian({3300, m, 1})); + for (int y=3301; y<3600; y++) + for (int m=1; m<=12; ++m) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({3300, 3, 1})==GregorianCalendar::fixedFromGregorian({3300, 3, 1})); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({3600, m, 1})==GregorianCalendar::fixedFromGregorian({3600, m, 1})); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({3600, m, 1})==GregorianCalendar::fixedFromGregorian({3600, m, 1})-1); + for (int y=3601; y<3800; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({3800, m, 1})==GregorianCalendar::fixedFromGregorian({3800, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({3800, m, 1})==GregorianCalendar::fixedFromGregorian({3800, m, 1})); + for (int y=3801; y<4000; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({4000, m, 1})==GregorianCalendar::fixedFromGregorian({4000, m, 1})); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({4000, m, 1})==GregorianCalendar::fixedFromGregorian({4000, m, 1})-1); + for (int y=4001; y<4200; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({4200, m, 1})==GregorianCalendar::fixedFromGregorian({4200, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({4200, m, 1})==GregorianCalendar::fixedFromGregorian({4200, m, 1})); + for (int y=4201; y<4400; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({4400, m, 1})==GregorianCalendar::fixedFromGregorian({4400, m, 1})); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({4400, m, 1})==GregorianCalendar::fixedFromGregorian({4400, m, 1})-1); + for (int y=4401; y<4700; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({4700, m, 1})==GregorianCalendar::fixedFromGregorian({4700, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({4700, m, 1})==GregorianCalendar::fixedFromGregorian({4700, m, 1})); + for (int y=4701; y<4800; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({4800, m, 1})==GregorianCalendar::fixedFromGregorian({4800, m, 1})); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({4800, m, 1})==GregorianCalendar::fixedFromGregorian({4800, m, 1})-1); + for (int y=4801; y<5100; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({5100, m, 1})==GregorianCalendar::fixedFromGregorian({5100, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({5100, m, 1})==GregorianCalendar::fixedFromGregorian({5100, m, 1})); + for (int y=5101; y<5200; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({5200, m, 1})==GregorianCalendar::fixedFromGregorian({5200, m, 1})); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({5200, m, 1})==GregorianCalendar::fixedFromGregorian({5200, m, 1})-1); + for (int y=5201; y<6400; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({6400, m, 1})==GregorianCalendar::fixedFromGregorian({6400, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({6400, m, 1})==GregorianCalendar::fixedFromGregorian({6400, m, 1})-2); + for (int y=6401; y<6500; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-2); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({6500, m, 1})==GregorianCalendar::fixedFromGregorian({6500, m, 1})-2); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({6500, m, 1})==GregorianCalendar::fixedFromGregorian({6500, m, 1})-1); + for (int y=6501; y<6800; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({6800, m, 1})==GregorianCalendar::fixedFromGregorian({6800, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({6800, m, 1})==GregorianCalendar::fixedFromGregorian({6800, m, 1})-2); + for (int y=6801; y<6900; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-2); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({6900, m, 1})==GregorianCalendar::fixedFromGregorian({6900, m, 1})-2); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({6900, m, 1})==GregorianCalendar::fixedFromGregorian({6900, m, 1})-1); + for (int y=6901; y<7200; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({7200, m, 1})==GregorianCalendar::fixedFromGregorian({7200, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({7200, m, 1})==GregorianCalendar::fixedFromGregorian({7200, m, 1})-2); + for (int y=7201; y<7400; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-2); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({7400, m, 1})==GregorianCalendar::fixedFromGregorian({7400, m, 1})-2); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({7400, m, 1})==GregorianCalendar::fixedFromGregorian({7400, m, 1})-1); + for (int y=7401; y<7600; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({7600, m, 1})==GregorianCalendar::fixedFromGregorian({7600, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({7600, m, 1})==GregorianCalendar::fixedFromGregorian({7600, m, 1})-2); + for (int y=7601; y<7800; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-2); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({7800, m, 1})==GregorianCalendar::fixedFromGregorian({7800, m, 1})-2); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({7800, m, 1})==GregorianCalendar::fixedFromGregorian({7800, m, 1})-1); + for (int y=7801; y<8000; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({8000, m, 1})==GregorianCalendar::fixedFromGregorian({8000, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({8000, m, 1})==GregorianCalendar::fixedFromGregorian({8000, m, 1})-2); + for (int y=8001; y<8300; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-2); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({8300, m, 1})==GregorianCalendar::fixedFromGregorian({8300, m, 1})-2); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({8300, m, 1})==GregorianCalendar::fixedFromGregorian({8300, m, 1})-1); + for (int y=8301; y<8400; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({8400, m, 1})==GregorianCalendar::fixedFromGregorian({8400, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({8400, m, 1})==GregorianCalendar::fixedFromGregorian({8400, m, 1})-2); + for (int y=8401; y<8700; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-2); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({8700, m, 1})==GregorianCalendar::fixedFromGregorian({8700, m, 1})-2); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({8700, m, 1})==GregorianCalendar::fixedFromGregorian({8700, m, 1})-1); + for (int y=8701; y<8800; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-1); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({8800, m, 1})==GregorianCalendar::fixedFromGregorian({8800, m, 1})-1); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({8800, m, 1})==GregorianCalendar::fixedFromGregorian({8800, m, 1})-2); + for (int y=8801; y<10000; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-2); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({10000, m, 1})==GregorianCalendar::fixedFromGregorian({10000, m, 1})-2); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({10000, m, 1})==GregorianCalendar::fixedFromGregorian({10000, m, 1})-3); + for (int y=10001; y<10100; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-3); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({10100, m, 1})==GregorianCalendar::fixedFromGregorian({10100, m, 1})-3); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({10100, m, 1})==GregorianCalendar::fixedFromGregorian({10100, m, 1})-2); + for (int y=10101; y<10400; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-2); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({10400, m, 1})==GregorianCalendar::fixedFromGregorian({10400, m, 1})-2); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({10400, m, 1})==GregorianCalendar::fixedFromGregorian({10400, m, 1})-3); + for (int y=10401; y<10500; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-3); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({10500, m, 1})==GregorianCalendar::fixedFromGregorian({10500, m, 1})-3); + for (int m=3; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({10500, m, 1})==GregorianCalendar::fixedFromGregorian({10500, m, 1})-2); + for (int y=10501; y<10800; y++) + for (int m=1; m<=12; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({y, m, 1})==GregorianCalendar::fixedFromGregorian({y, m, 1})-2); + for (int m=1; m<=2; m++) + QVERIFY(RevisedJulianCalendar::fixedFromRevisedJulian({10800, m, 1})==GregorianCalendar::fixedFromGregorian({10800, m, 1})-2); + QVERIFY(-214193==ISOCalendar::fixedFromISO({-586, 29, 7})); QVERIFY( -61387==ISOCalendar::fixedFromISO({-168, 49, 3})); QVERIFY( 25469==ISOCalendar::fixedFromISO({ 70, 39, 3})); @@ -1144,8 +1476,8 @@ void TestCalendars::testBalinesePawukon() const QVector<int>expect2038({1, 2, 1, 3, 4, 1, 4, 7, 1, 2}); QVERIFY2(BalinesePawukonCalendar::baliPawukonFromFixed(sample2038) == expect2038, - qPrintable(QString("Bali for %1 = %2").arg(QString::number(sample2038)) - .arg(printVec(BalinesePawukonCalendar::baliPawukonFromFixed(sample2038))))); + qPrintable(QString("Bali for %1 = %2").arg(QString::number(sample2038), + printVec(BalinesePawukonCalendar::baliPawukonFromFixed(sample2038))))); QVERIFY(-214193==BalinesePawukonCalendar::baliOnOrBefore({0, 1, 1, 1, 3, 1, 1, 5, 7, 3}, -214193)); QVERIFY( -61387==BalinesePawukonCalendar::baliOnOrBefore({1, 2, 2, 1, 4, 5, 4, 5, 5, 2}, -61387)); |