Skip to content

Commit

Permalink
Added Islamic calendar.
Browse files Browse the repository at this point in the history
  • Loading branch information
AsPJT committed Jul 7, 2023
1 parent 65055e5 commit e0daf97
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 6 deletions.
26 changes: 26 additions & 0 deletions Library/PAX_SAPIENTICA/Calendar/JulianDayNumber.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,32 @@ namespace paxs {
}
return CalBP{ value };
}
private:
// ヒジュラ暦の閏年かどうか
bool isIslamicLeapYear(const int year) const { return ((((11 * year) + 14) % 30) < 11); }
// ヒジュラ暦の月の日数計算
int getLastMonthDay(const int year, const int month) const {
return (((month % 2) == 1) || ((month == 12) && isIslamicLeapYear(year))) ? 30 : 29;
}
public:
// ヒジュラ暦を取得
IslamicDate toIslamicCalendar() {
// islamic_day(227014) = jdn(1948439)
const int islamic_day = day - 1721425;
// ヒジュラ暦以前の日付
if (islamic_day <= 227014) {
return IslamicDate(0, 0, 0);
}
IslamicDate ymd{};
// おおよその年から1年ずつ前倒しで検索
ymd.setYear((islamic_day - 227014) / 355);
while (islamic_day >= IslamicDate(ymd.getYear() + 1, 1, 1)) ymd.getYear()++;
// ムハッラム( Muharram ・1月)から月単位で検索
ymd.setMonth(1);
while (islamic_day > IslamicDate(ymd.getYear(), ymd.getMonth(), getLastMonthDay(ymd.getYear(), ymd.getMonth()))) ymd.getMonth()++;
ymd.setDay(islamic_day - IslamicDate(ymd.getYear(), ymd.getMonth(), 1) + 1);
return ymd;
}
};
using JDN_F64 = JulianDayNumber<double>;
using JDN_S32 = JulianDayNumber<std::int_least32_t>;
Expand Down
12 changes: 7 additions & 5 deletions Library/PAX_SAPIENTICA/Siv3D/Calendar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace paxs {

//
using CalendarVariant = std::variant<
GregorianDate, JulianDate, JapanDate, JDN_F64, JDN_S32, JDN_S64, CalBP
GregorianDate, JulianDate, JapanDate, JDN_F64, JDN_S32, JDN_S64, CalBP, IslamicDate
>;

/// @brief 出力に必要な日付の情報
Expand Down Expand Up @@ -192,8 +192,9 @@ namespace paxs {
OutputDate{language_text.getFindStart("calendar_japan"),JapanDate() },
OutputDate{language_text.getFindStart("calendar_gregorian"),GregorianDate() },
OutputDate{language_text.getFindStart("calendar_julian"), JulianDate() },
OutputDate{language_text.getFindStart("calendar_julian_day"), JDN_S64() }, // TODO
OutputDate{language_text.getFindStart("calendar_calbp"), CalBP()} // TODO
OutputDate{language_text.getFindStart("calendar_hijri"), IslamicDate() },
OutputDate{language_text.getFindStart("calendar_julian_day"), JDN_S64() },
OutputDate{language_text.getFindStart("calendar_calbp"), CalBP()}
};

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

// 格納
date_list[3].date = jdn;
date_list[4].date = jdn.toCalBP();
date_list[3].date = jdn.toIslamicCalendar();
date_list[4].date = jdn;
date_list[5].date = jdn.toCalBP();

static int count = 0; // 暦を繰り上げるタイミングを決めるためのカウンタ
++count;
Expand Down
2 changes: 1 addition & 1 deletion Library/PAX_SAPIENTICA/Siv3D/Main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ namespace paxs {
s3d::detail::Console_impl ci;
ci.open();
// フォルダ階層
const s3d::String path = U"./../../../../../";
const std::string path8 = "./../../../../../";
const s3d::String path = s3d::Unicode::FromUTF8(path8);

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

Expand Down
35 changes: 35 additions & 0 deletions Library/PAX_SAPIENTICA/Type/Date.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,41 @@ namespace paxs {
static DateOutputType getDateOutputType() { return DateOutputType::name_and_value; } // 暦名&年月日形式( Variant に用いているため定義)
};

// 年月日
class IslamicDate {
private:
DateYear year{};
DateMonth month{};
DateDay day{};
public:
// ヒジュラ暦の日付から絶対年代(日付)を計算
operator int() {
return (day + 29 * (month - 1) + month / 2
+ 354 * (year - 1) // 前年の閏日以外の日
+ (3 + (11 * year)) / 30 // 前年の閏日
+ 227014); // カレンダーの開始日の前日
}

IslamicDate() = default;
IslamicDate(const DateYear year_, const DateMonth month_, const DateDay day_)
:year(year_), month(month_), day(day_) {}
void setGengo(const DateGengo) const {} // 何もしない( Variant に用いているため定義)
void setYear(const DateYear year_) { year = year_; }
void setMonth(const DateMonth month_) { month = month_; }
void setDay(const DateDay day_) { day = day_; }
void setLeapMonth(const bool) const {} // 何もしない( Variant に用いているため定義)
DateGengo getGengo() const { return 0; }
DateYear& getYear() { return year; }
DateMonth& getMonth() { return month; }
DateDay& getDay() { return day; }
DateGengo cgetGengo() const { return 0; }
DateYear cgetYear() const { return year; }
DateMonth cgetMonth() const { return month; }
DateDay cgetDay() const { return day; }
static bool isLeapMonth() { return false; } // 閏月は必ず無い( Variant に用いているため定義)
static DateOutputType getDateOutputType() { return DateOutputType::name_and_ymd; } // 暦名&年月日形式( Variant に用いているため定義)
};

// 年月日
class GregorianDate {
private:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ GIS & Archaeological Simulator
||Julian calendar|
||Gregorian calendar|
||Japanese calendar|
||Islamic calendar|
||Julian day number|

## Language
Expand Down

0 comments on commit e0daf97

Please sign in to comment.