1 /*
2  * Copyright (C) 2020 Georg Zotti
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
17  */
18 
19 #include "StelTranslator.hpp"
20 #include "CopticCalendar.hpp"
21 #include "JulianCalendar.hpp"
22 #include "StelUtils.hpp"
23 #include "StelApp.hpp"
24 #include "StelCore.hpp"
25 
26 // Diocletian era
27 const int CopticCalendar::copticEpoch=JulianCalendar::fixedFromJulian({284, JulianCalendar::august, 29}); //! RD 103605.
28 
29 
CopticCalendar(double jd)30 CopticCalendar::CopticCalendar(double jd): JulianCalendar(jd)
31 {
32 	CopticCalendar::retranslate();
33 }
34 
35 QMap<int, QString> CopticCalendar::monthNames;
36 QMap<int, QString> CopticCalendar::dayNames;
37 
retranslate()38 void CopticCalendar::retranslate()
39 {
40 	// fill the name lists with translated month and day names
41 	monthNames={
42 		{ 1, qc_("Thoouth"  , "Coptic month name")},
43 		{ 2, qc_("Paope"    , "Coptic month name")},
44 		{ 3, qc_("Athōr"    , "Coptic month name")},
45 		{ 4, qc_("Koiak"    , "Coptic month name")},
46 		{ 5, qc_("Tōbe"     , "Coptic month name")},
47 		{ 6, qc_("Meshir"   , "Coptic month name")},
48 		{ 7, qc_("Paremotep", "Coptic month name")},
49 		{ 8, qc_("Parmoute" , "Coptic month name")},
50 		{ 9, qc_("Pashons"  , "Coptic month name")},
51 		{10, qc_("Paōne"    , "Coptic month name")},
52 		{11, qc_("Epēp"     , "Coptic month name")},
53 		{12, qc_("Mesorē"   , "Coptic month name")},
54 		{13, qc_("Epagomenē", "Coptic month name")}};
55 	dayNames={
56 		{ 0, qc_("Tkyriake" , "Coptic day name")},
57 		{ 1, qc_("Pesnau"   , "Coptic day name")},
58 		{ 2, qc_("Pshoment" , "Coptic day name")},
59 		{ 3, qc_("Peftoou"  , "Coptic day name")},
60 		{ 4, qc_("Ptiou"    , "Coptic day name")},
61 		{ 5, qc_("Psoou"    , "Coptic day name")},
62 		{ 6, qc_("Psabbaton", "Coptic day name")}};
63 }
64 
65 // Set a calendar date from the Julian day number
setJD(double JD)66 void CopticCalendar::setJD(double JD)
67 {
68 	this->JD=JD;
69 
70 	int rd=fixedFromJD(JD, true);
71 	parts=copticFromFixed(rd);
72 
73 	emit partsChanged(parts);
74 }
75 
76 // get a stringlist of calendar date elements sorted from the largest to the smallest.
77 // Year, Month, MonthName, Day, dayName
getDateStrings() const78 QStringList CopticCalendar::getDateStrings() const
79 {
80 	QStringList list;
81 	list << QString::number(parts.at(0));
82 	list << QString::number(parts.at(1));
83 	list << monthNames.value(parts.at(1));
84 	list << QString::number(parts.at(2));
85 	list << weekday(JD);
86 
87 	return list;
88 }
89 
90 // get a formatted complete string for a date
getFormattedDateString() const91 QString CopticCalendar::getFormattedDateString() const
92 {
93 	QStringList str=getDateStrings();
94 	return QString("%1, %2 - %3 (%4) - %5 %6")
95 			.arg(str.at(4)) // dayname
96 			.arg(str.at(3)) // day
97 			.arg(str.at(1)) // month, numerical
98 			.arg(str.at(2)) // month, name
99 			.arg(str.at(0)) // year
100 			.arg(q_("Era Martyrum"));// year
101 }
102 
103 // set date from a vector of calendar date elements sorted from the largest to the smallest.
104 // Year-Month[1...12]-Day[1...30]
105 // Time is not changed!
setDate(QVector<int> parts)106 void CopticCalendar::setDate(QVector<int> parts)
107 {
108 	this->parts=parts;
109 
110 	double rd=fixedFromCoptic(parts);
111 	// restore time from JD!
112 	double frac=StelUtils::fmodpos(JD+0.5+StelApp::getInstance().getCore()->getUTCOffset(JD)/24., 1.);
113 	JD=jdFromFixed(rd+frac, true);
114 
115 	emit jdChanged(JD);
116 }
117 
fixedFromCoptic(QVector<int> coptic)118 int CopticCalendar::fixedFromCoptic(QVector<int> coptic)
119 {
120 	const int year=coptic.at(0);
121 	const int month=coptic.at(1);
122 	const int day=coptic.at(2);
123 
124 	return copticEpoch - 1 + 365*(year-1) + StelUtils::intFloorDiv(year, 4) + 30*(month-1) + day;
125 }
126 
copticFromFixed(int rd)127 QVector<int> CopticCalendar::copticFromFixed(int rd)
128 {
129 	const int year  = StelUtils::intFloorDiv(4 * (rd-copticEpoch) + 1463, 1461);
130 	const int month = StelUtils::intFloorDiv(rd-fixedFromCoptic({year, 1, 1}), 30)+1;
131 	const int day   = rd + 1 - fixedFromCoptic({year, month, 1});
132 
133 	return {year, month, day};
134 }
135 
136 // return name of week day
weekday(double jd)137 QString CopticCalendar::weekday(double jd)
138 {
139 	const int dow = StelUtils::getDayOfWeek(jd+StelApp::getInstance().getCore()->getUTCOffset(jd)/24.);
140 	return dayNames.value(dow);
141 }
142 
143 // returns true for leap years
isLeap(int year)144 bool CopticCalendar::isLeap(int year)
145 {
146 	return StelUtils::imod(year, 4)==3;
147 }
148 
149