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