Skip to content

Commit e0daf97

Browse files
committed
Added Islamic calendar.
1 parent 65055e5 commit e0daf97

File tree

5 files changed

+70
-6
lines changed

5 files changed

+70
-6
lines changed

Library/PAX_SAPIENTICA/Calendar/JulianDayNumber.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,32 @@ namespace paxs {
171171
}
172172
return CalBP{ value };
173173
}
174+
private:
175+
// ヒジュラ暦の閏年かどうか
176+
bool isIslamicLeapYear(const int year) const { return ((((11 * year) + 14) % 30) < 11); }
177+
// ヒジュラ暦の月の日数計算
178+
int getLastMonthDay(const int year, const int month) const {
179+
return (((month % 2) == 1) || ((month == 12) && isIslamicLeapYear(year))) ? 30 : 29;
180+
}
181+
public:
182+
// ヒジュラ暦を取得
183+
IslamicDate toIslamicCalendar() {
184+
// islamic_day(227014) = jdn(1948439)
185+
const int islamic_day = day - 1721425;
186+
// ヒジュラ暦以前の日付
187+
if (islamic_day <= 227014) {
188+
return IslamicDate(0, 0, 0);
189+
}
190+
IslamicDate ymd{};
191+
// おおよその年から1年ずつ前倒しで検索
192+
ymd.setYear((islamic_day - 227014) / 355);
193+
while (islamic_day >= IslamicDate(ymd.getYear() + 1, 1, 1)) ymd.getYear()++;
194+
// ムハッラム( Muharram ・1月)から月単位で検索
195+
ymd.setMonth(1);
196+
while (islamic_day > IslamicDate(ymd.getYear(), ymd.getMonth(), getLastMonthDay(ymd.getYear(), ymd.getMonth()))) ymd.getMonth()++;
197+
ymd.setDay(islamic_day - IslamicDate(ymd.getYear(), ymd.getMonth(), 1) + 1);
198+
return ymd;
199+
}
174200
};
175201
using JDN_F64 = JulianDayNumber<double>;
176202
using JDN_S32 = JulianDayNumber<std::int_least32_t>;

Library/PAX_SAPIENTICA/Siv3D/Calendar.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ namespace paxs {
4343

4444
//
4545
using CalendarVariant = std::variant<
46-
GregorianDate, JulianDate, JapanDate, JDN_F64, JDN_S32, JDN_S64, CalBP
46+
GregorianDate, JulianDate, JapanDate, JDN_F64, JDN_S32, JDN_S64, CalBP, IslamicDate
4747
>;
4848

4949
/// @brief 出力に必要な日付の情報
@@ -192,8 +192,9 @@ namespace paxs {
192192
OutputDate{language_text.getFindStart("calendar_japan"),JapanDate() },
193193
OutputDate{language_text.getFindStart("calendar_gregorian"),GregorianDate() },
194194
OutputDate{language_text.getFindStart("calendar_julian"), JulianDate() },
195-
OutputDate{language_text.getFindStart("calendar_julian_day"), JDN_S64() }, // TODO
196-
OutputDate{language_text.getFindStart("calendar_calbp"), CalBP()} // TODO
195+
OutputDate{language_text.getFindStart("calendar_hijri"), IslamicDate() },
196+
OutputDate{language_text.getFindStart("calendar_julian_day"), JDN_S64() },
197+
OutputDate{language_text.getFindStart("calendar_calbp"), CalBP()}
197198
};
198199

199200
font_pulldown = setFont(s3d::FontMethod::SDF, 16, path8, "font_path", language_text);
@@ -335,8 +336,9 @@ namespace paxs {
335336
date_list[std::size_t(KoyomiEnum::koyomi_japan)].date = jp_date;
336337

337338
// 格納
338-
date_list[3].date = jdn;
339-
date_list[4].date = jdn.toCalBP();
339+
date_list[3].date = jdn.toIslamicCalendar();
340+
date_list[4].date = jdn;
341+
date_list[5].date = jdn.toCalBP();
340342

341343
static int count = 0; // 暦を繰り上げるタイミングを決めるためのカウンタ
342344
++count;

Library/PAX_SAPIENTICA/Siv3D/Main.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ namespace paxs {
4747
s3d::detail::Console_impl ci;
4848
ci.open();
4949
// フォルダ階層
50-
const s3d::String path = U"./../../../../../";
5150
const std::string path8 = "./../../../../../";
51+
const s3d::String path = s3d::Unicode::FromUTF8(path8);
5252

5353
paxs::Language language_text(path8 + "Data/Language/Text.txt");
5454

Library/PAX_SAPIENTICA/Type/Date.hpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,41 @@ namespace paxs {
5858
static DateOutputType getDateOutputType() { return DateOutputType::name_and_value; } // 暦名&年月日形式( Variant に用いているため定義)
5959
};
6060

61+
// 年月日
62+
class IslamicDate {
63+
private:
64+
DateYear year{};
65+
DateMonth month{};
66+
DateDay day{};
67+
public:
68+
// ヒジュラ暦の日付から絶対年代(日付)を計算
69+
operator int() {
70+
return (day + 29 * (month - 1) + month / 2
71+
+ 354 * (year - 1) // 前年の閏日以外の日
72+
+ (3 + (11 * year)) / 30 // 前年の閏日
73+
+ 227014); // カレンダーの開始日の前日
74+
}
75+
76+
IslamicDate() = default;
77+
IslamicDate(const DateYear year_, const DateMonth month_, const DateDay day_)
78+
:year(year_), month(month_), day(day_) {}
79+
void setGengo(const DateGengo) const {} // 何もしない( Variant に用いているため定義)
80+
void setYear(const DateYear year_) { year = year_; }
81+
void setMonth(const DateMonth month_) { month = month_; }
82+
void setDay(const DateDay day_) { day = day_; }
83+
void setLeapMonth(const bool) const {} // 何もしない( Variant に用いているため定義)
84+
DateGengo getGengo() const { return 0; }
85+
DateYear& getYear() { return year; }
86+
DateMonth& getMonth() { return month; }
87+
DateDay& getDay() { return day; }
88+
DateGengo cgetGengo() const { return 0; }
89+
DateYear cgetYear() const { return year; }
90+
DateMonth cgetMonth() const { return month; }
91+
DateDay cgetDay() const { return day; }
92+
static bool isLeapMonth() { return false; } // 閏月は必ず無い( Variant に用いているため定義)
93+
static DateOutputType getDateOutputType() { return DateOutputType::name_and_ymd; } // 暦名&年月日形式( Variant に用いているため定義)
94+
};
95+
6196
// 年月日
6297
class GregorianDate {
6398
private:

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ GIS & Archaeological Simulator
1313
||Julian calendar|
1414
||Gregorian calendar|
1515
||Japanese calendar|
16+
||Islamic calendar|
1617
||Julian day number|
1718

1819
## Language

0 commit comments

Comments
 (0)