目次
サンプル・プログラムの実行例
サンプル・プログラム
tripleCalendar.php | サンプル・プログラム本体。 |
pahooCalendar.php | 暦・潮位計算クラス pahooCalendar。 暦・潮位計算クラスの使い方は「PHPで二十四節気・七十二候一覧を作成」「PHPで月齢を計算」「PHPで日出没・月出没・月齢・潮を計算」「PHPで潮位を計算する」などを参照。include_path が通ったディレクトリに配置すること。 |
pahooInputData.php | データ入力に関わる関数群。 使い方は「PHPでGET/POSTでフォームから値を受け取る」「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
バージョン | 更新日 | 内容 |
---|---|---|
1.0.0 | 2024/03/17 | 初版 |
バージョン | 更新日 | 内容 |
---|---|---|
4.5.0 | 2024/03/17 | ヒジュラ暦メソッドを追加 |
4.4.1 | 2024/03/17 | getCabinetOfficeHolidayTable() -- bug-fix |
4.4.0 | 2024/02/25 | 内閣府の祝日表を参照できるようにした |
4.3.2 | 2023/02/11 | getSolarTerm72() 表記改訂:水澤腹堅→水沢腹堅 |
4.3.1 | 2023/02/03 | 表記改訂:バクムーン→バックムーン,スタージャンムーン→スタージョンムーン,七十二候 |
バージョン | 更新日 | 内容 |
---|---|---|
1.5.0 | 2024/01/28 | exitIfExceedVersion() 追加 |
1.4.2 | 2024/01/28 | exitIfLessVersion() メッセージ修正 |
1.4.1 | 2023/09/30 | コメントの訂正 |
1.4.0 | 2023/09/09 | $_GET, $_POST参照をfilter_input()関数に置換 |
1.3.0 | 2023/07/11 | roundFloat() 追加 |
準備:初期値など
48: //カレンダーの横幅(ピクセル)
49: define('CALENDAR_WIDTH', 600);
50:
51: //入力可能な西暦年
52: define('YEAR_MIN', 2000); //最小値【変更不可】
53: define('YEAR_MAX', 2099); //最大値【変更不可】
54:
55: //入力可能な作成期間(ヶ月)
56: define('PERIOD_MIN', 1); //最小値【変更不可】
57: define('PERIOD_MAX', 36); //最大値【変更不可】
58: define('PERIOD_DEF', 3); //初期値
59:
60: //require_once()で呼ぶファイルはinclude_pathが通っているフォルダに配置すること。
61: //暦計算クラス
62: require_once('pahooCalendar.php');
63:
64: //データ入力に関わる関数群
65: require_once('pahooInputData.php');
66:
67: //キャッシュ保持時間(分) 0:キャッシュしない
68: //内閣府へのアクセス負荷軽減のため,1440分(24時間)以上のキャッシュ保持をお勧めします.
69: define('LIFE_CACHE', 1440);
70:
71: //キャッシュ・ディレクトリ
72: //書き込み可能で,外部からアクセスされないディレクトリを指定してください.
73: //最大150Mバイトを消費します.
74: define('DIR_CACHE', './pcacheholiday/');
75:
76: //キャッシュ処理に関わるクラス:include_pathが通ったディレクトリに配置
77: require_once('pahooCache.php');
データ入力に関わる関数群 "pahooInputData.php" および暦計算クラス・ファイル "pahooCalendar.php" はinclude_pathが通ったディレクトリに配置すること。
ヒジュラ暦とは
コーラン(クルアーン)に「本当にアッラーの御許で、(1年の)月数は、12か月である」(第9章36節)、「本当に(聖月を)延ばすことは、不信心を増長させ、それで不信者は誤って導かれている。ある年は(聖月を)普通の月とし、(他の年は)聖月とする」(同37節)と記されていることから、ヒジュラ暦は月の満ち欠けに基づく純粋な太陰暦で、しかも新月ではなく細い三日月の日を月の第1日とする。日本の旧暦のように季節の調整をする太陰太陽暦と異なる独特な暦であり、われわれが現在使っているグレゴリオ暦から単純に換算することができない。
月の満ち欠けの周期は約29.5日(朔望月)で、ヒジュラ暦では29日の月と30日の月が互い違いに並ぶ。1年は354日であり、グレゴリオ暦よりも11日も短い。
そして、朔望月の小数点以下は0.5日=12時間ではなく、12時間44分である。このため、1年間で44分×12=8時間48分のズレが生じる。これを補正するため、年によっては最後の月を29日ではなく30日とする追加日を設ける(うるう日とは呼ばない)。
標準的なヒジュラ暦では、30年周期で11回――2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29年目――の追加日を置くが、この置き方は国や地域によって異なる。
季節と無関係に刻まれるカレンダーというのは、われわれにとっては奇異なものに見える。
これは想像だが、原初のイスラム宗教圏には農耕民族が少なく、季節に合わせたカレンダーを作ることより、戒律を優先したのではないだろうが。
解説:ユリウス日からヒジュラ暦を求める
555: /**
556: * ユリウス日からヒジュラ暦を求める.
557: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-61-01.shtm
558: * @param float $jd ユリウス日
559: * @return array(ヒジュラ暦の年,月,日)
560: */
561: function JD2Hijri($jd) {
562: //ヒジュラ暦の基準日(グレゴリオ暦622年7月16日)をユリウス日で表した値
563: $baseJD = 1948440;
564:
565: $l = $this->interHijri($jd - $baseJD + 10633);
566: $n = $this->interHijri(($l - 1) / 10631);
567: $l = $l - 10631 * $n + 354;
568: $j = $this->interHijri((10985 - $l) / 5316) * $this->interHijri((50 * $l) / 17719) + $this->interHijri($l / 5670) * $this->interHijri((43 * $l) / 15238);
569: $l = $l - $this->interHijri((30 - $j) / 15) * $this->interHijri((17719 * $j) / 50) - $this->interHijri($j / 16) * $this->interHijri((15238 * $j) / 43) + 29;
570:
571: //ヒジュラ暦の月
572: $hijriMonth = (int)($this->interHijri((24 * $l) / 709));
573: //ヒジュラ暦の日
574: $hijriDay = (int)($l - $this->interHijri((709 * $hijriMonth) / 24));
575: //ヒジュラ暦の年
576: $hijriYear = (int)(30 * $n + $j - 30);
577:
578: return array($hijriYear, $hijriMonth, $hijriDay);
579: }
546: /**
547: * 演算誤差修正用
548: * @param float $x
549: * @return int 結果
550: */
551: function interHijri($x) {
552: return ($x < -0.0000001) ? ceil($x - 0.0000001) : floor($x + 0.0000001);
553: }
解説:西暦からヒジュラ暦を求める
581: /**
582: * 西暦からヒジュラ暦を求める.
583: * 1581年以前はユリウス暦,1582年以降はグレゴリオ暦として計算する.
584: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-61-01.shtm
585: * @param int $year, $month, $day 西暦による年月日
586: * @return array(ヒジュラ暦の年,月,日)
587: */
588: function AD2Hijri($year, $month, $day) {
589: $jd = $this->AD2JD($year, $month, $day);
590:
591: return $this->JD2Hijri($jd);
592: }
解説:ラマダン月を求める
594: /**
595: * ラマダン月かどうかを判定する.
596: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-61-01.shtm
597: * @param int $year, $month, $day ヒジュラ暦による年月日
598: * @return bool TRUE:ラマダン月である/FALSE:ではない
599: */
600: function isRamadan($year, $month, $day) {
601: return ($month == 9);
602: }
解説:カレンダー作成
185: /**
186: * 1ヶ月分のカレンダーを作成
187: * @param object $pcl pahooCalendarオブジェクト
188: * @param int $start 週の開始曜日(0:日曜日, 1:月曜日...6:土曜日)
189: * @param int $year 西暦年
190: * @param int $month 月
191: * @return string HTMLコンテンツ/FALSE:エラー
192: */
193: function makeCalendar($pcl, $start, $year, $month) {
194: //月のエラーチェック
195: if ($month < 1 && $month > 12) return FALSE;
196:
197: $html =<<< EOT
198: <table class="calendar">
199: <tr>
200: <th colspan="7"><span class="large">{$year}年 {$month}月</span></th>
201: </tr>
202: <tr>
203:
204: EOT;
205:
206: //曜日の行
207: for ($i = 0; $i < 7; $i++) {
208: $n = ($start + $i) % 7;
209: if ($n == 6) $class = 'blue';
210: else if ($n == 0) $class = 'red';
211: else $class = 'black';
212: $str = $pcl->__getWeekString($n);
213: $html .= "<th><span class=\"{$class}\">{$str}</span></th>";
214: }
215: $html .= "</tr>\n";
216:
217: //カレンダー本体
218: $wn1 = $pcl->getWeekNumber($year, $month, 1); //月の最初の曜日
219: $dim = $pcl->getDaysInMonth($year, $month); //月の最後の日
220: $cnt = 0;
221: $flag = FALSE;
222: $n = $start;
223: $day = 1;
224: while (1) {
225: if ($cnt % 7 == 0) $html .= "<tr>\n";
226: //曜日の色
227: if ($n % 7 == 6) $class = 'blue';
228: else if ($n % 7 == 0) $class = 'red';
229: else $class = 'black';
230: if ($n % 7 == $wn1) $flag = TRUE;
231: //表示開始
232: if ($flag) {
233: //祝日
234: $holiday = $pcl->getHoliday($year, $month, $day);
235: //ヒジュラ暦
236: list($hy, $hm, $hd) = $pcl->AD2Hijri($year, $month, $day);
237: $hijri = sprintf('%d年<br>%d月%d日', $hy, $hm, $hd);
238: $color = $pcl->isRamadan($hy, $hm, $hd) ? 'orange' : 'green';
239:
240: //表示
241: $html .=<<< EOT
242: <td>
243: <span class="large {$class}">{$day}</span>
244: <div class="narrow">
245: <span class="small red">{$holiday}</span><br><br>
246: <span class="small {$color}">{$hijri}</span>
247: </div>
248: </td>
249:
250: EOT;
251: $day++;
252: if ($day > $dim) break;
253: } else {
254: $html .= "<td> </td>";
255: }
256: $cnt++;
257: $n++;
258: if ($cnt % 7 == 0) $html .= "</tr>\n";
259: }
260: //最後の日以降の処理
261: $cnt++;
262: while ($cnt % 7 != 0) {
263: $html .= "<td> </td>";
264: $cnt++;
265: if ($cnt % 7 == 0) $html .= "</tr>\n";
266: }
267:
268: $html .= "</table>\n";
269:
270: return $html;
271: }
週の開始曜日を自由に設定できるようにするための工夫をしている。
カレンダー本体を作成する処理では、まず、月の最初の曜日 $wn1 と、月の最後の日 $dim を計算しておく。
$wn1 と週の開始曜日 $start が一致するまでは変数 $flag がFALSEのままで、この時は日付を入れずに空のままにしておく。
$flag がTRUEになったら日付を入れてゆく。あわせて、祝日とヒジュラ暦の計算を行う。
$dim に達したらループを抜け出し、行末まで空白のセルを追加してゆく。
参考サイト
- PHPで万年カレンダーを作る:ぱふぅ家のホームページ
- イスラム暦:国立天文台暦計算室
- こよみの学校 第13回『聖遷の年を紀元とするヒジュラ暦』:暦生活