目次
サンプル・プログラムの実行例

サンプル・プログラム
tripleCalendar.php | サンプル・プログラム本体。 |
pahooCalendar.php | 暦・潮位計算クラス pahooCalendar。 暦・潮位計算クラスの使い方は「PHPで二十四節気・七十二候一覧を作成」「PHPで月齢を計算」「PHPで日出没・月出没・月齢・潮を計算」「PHPで潮位を計算する」などを参照。include_path が通ったディレクトリに配置すること。 |
pahooInputData.php | データ入力に関わる関数群。 使い方は「PHPでGET/POSTでフォームから値を受け取る」「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
バージョン | 更新日 | 内容 |
---|---|---|
2.0.2 | 2023/10/06 | bugfix:makeCalendar() -- 祝日をredに |
2.0.1 | 2023/01/18 | bug-fix |
2.0.0 | 2023/01/14 | 土用の二の丑の日、天赦日を追加 |
1.9 | 2022/06/05 | pahooInputData.php分離,カレンダー作成期間追加,タイトル変更 |
1.8 | 2022/05/27 | 2033年問題解決案を追加;定数 RESOLVE2033 |
バージョン | 更新日 | 内容 |
---|---|---|
4.5.1 | 2025/05/31 | deg2ddmm(), deg2hhmm() 不具合修正 |
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() 表記改訂:水澤腹堅→水沢腹堅 |
バージョン | 更新日 | 内容 |
---|---|---|
1.8.1 | 2025/03/15 | validRegexPattern() -- debug |
1.8.0 | 2024/11/12 | validRegexPattern() 追加 |
1.7.0 | 2024/10/09 | validURL() validEmail() 追加 |
1.6.0 | 2024/10/07 | isButton() -- buttonタグに対応 |
1.5.0 | 2024/01/28 | exitIfExceedVersion() 追加 |
準備:初期値など
tripleCalendar.php
39: //カレンダーの横幅(ピクセル)
40: define('CALENDAR_WIDTH', 600);
41:
42: //旧暦2033年問題解決案 0:解決しない,1:案1,2:案2,3:対応案3
43: define('RESOLVE2033', 1);
44:
45: //入力可能な西暦年
46: define('YEAR_MIN', 2000); //最小値【変更不可】
47: define('YEAR_MAX', 2099); //最大値【変更不可】
48:
49: //表示言語(jp:日本語, en:英語, en3:英語略記)
50: define('LANGUAGE', 'jp');
51:
52: //世界時からの時差(日本標準時)
53: define('UTCDIFF', +9.0);
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');
後述する旧暦2033年問題解決案は定数 RESOLVE2033 に定義しておく。解決しないを選択すると、西暦2033年(令和15年)以降の旧暦は計算しなくなる。
データ入力に関わる関数群は別ファイル "pahooInputData.php" に分離しており、include_path が通ったディレクトリに配置すること。
また、暦計算クラス・ファイル "pahooCalendar.php" もinclude_pathが通ったディレクトリに配置すること。
解説:朔を求める
解説:旧暦の計算
pahooCalendar.php
2365: /**
2366: * 指定した年のグレゴオリオ暦=旧暦テーブルを作成する.
2367: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm
2368: * @param int $year 西暦年
2369: * @param int $method 2033年問題解決案
2370: * 0:解決しない,1:案1,2:案2,3:案3(省略時:0)
2371: * @return なし
2372: */
2373: function makeLunarCalendar($year, $method=0) {
2374: $this->resolve2033 = $method;
2375:
2376: if (($method == 0) && ($year >= 2033)) {
2377: $this->error = TRUE;
2378: $this->errmsg = '2033年以降は正しい旧暦計算ができません';
2379: return;
2380: }
2381:
2382: unset($this->tblmoon);
2383: $this->tblmoon = array();
2384:
2385: //前年の冬至を求める
2386: for ($day = 1; $day <= 31; $day++) {
2387: $lsun = $this->longitude_sun($year - 1, 12, $day, 0, 0, 0);
2388: if (floor($lsun / 15.0) > 17) break;
2389: }
2390: $d1 = $day - 1; //冬至
2391:
2392: //翌年の雨水を求める
2393: for ($day = 1; $day <= 31; $day++) {
2394: $lsun = $this->longitude_sun($year + 1, 2, $day, 0, 0, 0);
2395: if (floor($lsun / 15.0) > 22) break;
2396: }
2397: $d2 = $day - 1; //雨水
2398:
2399: //朔の日を求める
2400: $cnt = 0;
2401: $dd = $d1;
2402: $mm = 12;
2403: $yy = $year - 1;
2404:
2405: //ver.4.0.1:朔を求める手段を next_newmoon() に変更
2406: while ($yy <= $year + 1) {
2407: list($yy, $mm, $dd) = $this->next_newmoon($yy, $mm, $dd, 0, 0, 0, $this->TDIFF, 2);
2408: $this->tblmoon[$cnt]['year'] = $yy;
2409: $this->tblmoon[$cnt]['month'] = $mm;
2410: $this->tblmoon[$cnt]['day'] = $dd;
2411: $this->tblmoon[$cnt]['age'] = $this->moon_age($yy, $mm, $dd, 0, 0, 0);
2412: $this->tblmoon[$cnt]['jd'] = $this->Gregorian2JD($yy, $mm, $dd, 0, 0, 0);
2413: $cnt++;
2414: $dd = $dd + 26.0; //次の計算基準は26日後
2415: if ($dd > $this->getDaysInMonth($yy, $mm)) {
2416: $dd = 1;
2417: $mm++;
2418: if ($mm > 12) {
2419: $mm = 1;
2420: $yy++;
2421: }
2422: }
2423: }
2424:
2425: //中気(二十四節気の偶数番)を求める
2426: $tblsun = array();
2427: $cnt = 0;
2428: $dd = $d1;
2429: $mm = 12;
2430: $yy = $year - 1;
2431: while ($yy <= $year + 1) {
2432: $dm = $this->getDaysInMonth($yy, $mm);
2433: while ($dd <= $dm) {
2434: $l1 = $this->longitude_sun($yy, $mm, $dd, 0, 0, 0);
2435: $l2 = $this->longitude_sun($yy, $mm, $dd, 24, 0, 0);
2436: $n1 = floor($l1 / 15.0);
2437: $n2 = floor($l2 / 15.0);
2438: if (($n2 != $n1) && ($n2 % 2 == 0)) {
2439: $tblsun[$cnt]['jd'] = $this->Gregorian2JD($yy, $mm, $dd, 0, 0, 0);
2440: $oldmonth = floor($n2 / 2.0) + 2;
2441: if ($oldmonth > 12) $oldmonth -= 12;
2442: $tblsun[$cnt]['oldmonth'] = $oldmonth;
2443: $cnt++;
2444: }
2445: $dd++;
2446: }
2447: $mm++;
2448: $dd = 1;
2449: if ($mm > 12) {
2450: $yy++;
2451: $mm = 1;
2452: }
2453: }
2454:
2455: //月の名前を決める
2456: $n1 = count($this->tblmoon);
2457: $n2 = count($tblsun);
2458: for ($i = 0; $i < $n1 - 1; $i++) {
2459: for ($j = 0; $j < $n2; $j++) {
2460: if (($this->tblmoon[$i]['jd'] <= $tblsun[$j]['jd'])
2461: && ($this->tblmoon[$i + 1]['jd'] > $tblsun[$j]['jd'])) {
2462: $this->tblmoon[$i]['oldmonth'] = $tblsun[$j]['oldmonth'];
2463: $this->tblmoon[$i]['oldleap'] = FALSE;
2464: $this->tblmoon[$i + 1]['oldmonth'] = $tblsun[$j]['oldmonth'];
2465: $this->tblmoon[$i + 1]['oldleap'] = TRUE;
2466: break;
2467: }
2468: }
2469: }
2470:
2471: //冬至・春分・夏至・秋分の補正 - version 3.72
2472: foreach ($this->tblmoon as $key=>$arr) {
2473: $yy1 = $this->tblmoon[$key]['year'];
2474: $mm1 = $this->tblmoon[$key]['month'];
2475: $dd1 = $this->tblmoon[$key]['day'];
2476: $l1 = (float)$this->longitude_sun($yy1, $mm1, $dd1, 0, 0, 0);
2477: if (isset($this->tblmoon[$key + 1])) {
2478: $yy2 = $this->tblmoon[$key + 1]['year'];
2479: $mm2 = $this->tblmoon[$key + 1]['month'];
2480: $dd2 = $this->tblmoon[$key + 1]['day'];
2481: } else {
2482: break;
2483: }
2484: $l2 = (float)$this->longitude_sun($yy2, $mm2, $dd2, 0, 0, 0);
2485: if ((($l1 > 345.0 || $l1 <= 0.0)) && (($l2 > 345.0) || $l2 < 15.0)) {
2486: $this->tblmoon[$key]['oldmonth'] = 11;
2487: } else if (($l1 > 75.0) && ($l2 < 90.0)) {
2488: $this->tblmoon[$key]['oldmonth'] = 2;
2489: } else if (($l1 > 165.0) && ($l2 < 180.0)) {
2490: $this->tblmoon[$key]['oldmonth'] = 5;
2491: } else if (($l1 > 255.0) && ($l2 < 270.0)) {
2492: $this->tblmoon[$key]['oldmonth'] = 8;
2493: }
2494: }
2495:
2496: //2033年問題の解決案
2497: if ($method > 0) {
2498: $this->resolveLunarCalendar2033($method);
2499: }
2500: }

旧暦を求めたいときには、事前にメソッド makeLunarCalendar を実行する必要がある。
また、makeLunarCalendar は、直前の冬至から1年分の旧暦変換テーブルしか作成しないことに留意されたい。後述するが、3ヵ月超のカレンダーを生成するには、makeLunarCalendar を複数回コールする必要がある。
引数 $method は、後述する旧暦2033年問題の解決案の番号を指定する。これは省略可能で、省略時には解決を行わず、西暦2033年(令和15年)以降の旧暦は計算できなくなる。

グレゴリオ暦から旧暦を求める手順は、「旧暦と六曜を作りましょう」を参考にした。
天保暦のルールに則り、次の流れで旧暦を決めてゆく。
- 前年の冬至を求める。
- 翌年の雨水を求める。
- 1~2の期間中の中気(※)を配列 $tblsun に格納する。
- 朔日と中を比較して、月の名前と閏月を決めてゆく。
- 冬至を含む月は11月、春分を含む月は2月、夏至を含む月は5月、秋分を含む月は8月となるように調整する。
pahooCalendar.php
2584: /**
2585: * 指定した年月日の旧暦を求める.
2586: * このメソッドを実行する前に,makeLunarCalendar()を実行すること.
2587: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_makeLunarCalendar
2588: * @param int $year 西暦年
2589: * @param int $month 月
2590: * @param int $day 日
2591: * @return array(旧暦月,日,閏月フラグ)/FALSE:旧暦計算不能
2592: */
2593: function Gregorian2Lunar($year, $month, $day) {
2594: //2033年問題チェック
2595: if (($this->resolve2033 == 0) && ($year >= 2033)) {
2596: $this->error = TRUE;
2597: $this->errmsg = '2033年以降は正しい旧暦計算ができません';
2598: return FALSE;
2599: }
2600:
2601: //旧暦を求める
2602: $items = array();
2603: $jd = $this->Gregorian2JD($year, $month, $day, 0, 0, 0);
2604: $str = '';
2605: $n1 = count($this->tblmoon);
2606: for ($i = 0; $i < $n1 - 1; $i++) {
2607: if ($jd < $this->tblmoon[$i + 1]['jd']) {
2608: $day = floor($jd - $this->tblmoon[$i]['jd']) + 1;
2609: $items = array($this->tblmoon[$i]['oldmonth'], $day, $this->tblmoon[$i]['oldleap']);
2610: break;
2611: }
2612: }
2613:
2614: //旧暦テーブルが無い
2615: if (count($items) == 0) {
2616: $this->error = TRUE;
2617: $this->errmsg = '旧暦テーブルがありません';
2618: return FALSE;
2619: }
2620:
2621: return $items;
2622: }
旧暦変換テーブルにマッチする値がないときには、エラーを返す。
解説:旧暦2033年問題の解決案
これは、1844年(天保14年)に天保暦が導入されてから初めて起きる事態だが、天保暦は1872年(明治5年)に廃止されているために正式な解決法は用意されていない。2033年(令和15年)7月から2034年(令和16年)3月までの旧暦計算に影響を及ぼす。
一方で、国立天文台が次のような解決案を提示している(国立天文台は旧暦を決める機関ではないので、あくまで「提案」)。また、日本カレンダー暦文化振興協会も、「2033年旧暦閏月問題の見解」として、案1が望ましいと述べているものの、「これをベースに広く意見を求めるという手順が望ましい」と結論づけている。

案1‥‥2033年12月21日の冬至を優先し、冬至を含む月を11月とする。翌12月は中気がないので閏11月となる。
案2‥‥2033年9月23日の秋分を優先し、秋分を含む月を8月とする。前8月は中気がないので閏7月となる。
案3‥‥2033年12月21日の冬至を優先し、2024年(令和6年)2月18日の雨水が1月になると考え、翌2月は中気がないので閏1月となる。
朔日 | 中気1 | 中気2 | 案1 | 案2 | 案3 |
---|---|---|---|---|---|
2033/07/26 | 処暑(08/23) | --- | 7月 | 7月 | 7月 |
2033/08/25 | --- | --- | 8月 | 閏7月 | 8月 |
2033/09/23 | 秋分(09/23) | --- | 9月 | 8月 | 9月 |
2033/10/23 | 霜降(10/23) | --- | 10月 | 9月 | 10月 |
2033/11/22 | 小雪(11/22) | 冬至(12/21) | 11月 | 10月 | 11月 |
2033/12/22 | --- | --- | 閏11月 | 11月 | 12月 |
2034/01/20 | 大寒(01/20) | 雨水(02/18) | 12月 | 12月 | 1月 |
2034/02/19 | --- | --- | 1月 | 1月 | 閏1月 |
2034/03/20 | 春分(03/20) | --- | 2月 | 2月 | 2月 |
pahooCalendar.php
2502: /**
2503: * 旧暦2033年問題の解決案を旧暦テーブルに書き込む.
2504: * 旧暦(天保暦)は2033年に10月がなくなる問題がある.旧暦は廃止されているため正式な解決策はないのだが,案1~3の3つのパターンで旧暦テーブルを修正する.
2505: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_resolveLunarCalendar2033
2506: * @param int $method 2033年問題解決案
2507: * 1:案1,2:案2,3:案3(省略時:1)
2508: * @return なし
2509: * 参考URL https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm
2510: */
2511: function resolveLunarCalendar2033($method=1) {
2512: //補正テーブル
2513: //案1
2514: static $table01 = array(
2515: //西暦年, 月, 日, 旧暦月, 閏月か否か
2516: array(2033, 7, 26, 7, FALSE),
2517: array(2033, 8, 25, 8, FALSE),
2518: array(2033, 9, 23, 9, FALSE),
2519: array(2033, 10, 23, 10, FALSE),
2520: array(2033, 11, 22, 11, FALSE),
2521: array(2033, 12, 22, 11, TRUE),
2522: array(2034, 1, 20, 12, FALSE),
2523: array(2034, 2, 19, 1, FALSE),
2524: array(2034, 3, 20, 2, FALSE),
2525: );
2526: //案2
2527: static $table02 = array(
2528: //西暦年, 月, 日, 旧暦月, 閏月か否か
2529: array(2033, 7, 26, 7, FALSE),
2530: array(2033, 8, 25, 7, TRUE),
2531: array(2033, 9, 23, 8, FALSE),
2532: array(2033, 10, 23, 9, FALSE),
2533: array(2033, 11, 22, 10, FALSE),
2534: array(2033, 12, 22, 11, FALSE),
2535: array(2034, 1, 20, 12, FALSE),
2536: array(2034, 2, 19, 1, FALSE),
2537: array(2034, 3, 20, 2, FALSE),
2538: );
2539: //案3
2540: static $table03 = array(
2541: //西暦年, 月, 日, 旧暦月, 閏月か否か
2542: array(2033, 7, 26, 7, FALSE),
2543: array(2033, 8, 25, 8, FALSE),
2544: array(2033, 9, 23, 9, FALSE),
2545: array(2033, 10, 23, 10, FALSE),
2546: array(2033, 11, 22, 11, FALSE),
2547: array(2033, 12, 22, 12, FALSE),
2548: array(2034, 1, 20, 1, FALSE),
2549: array(2034, 2, 19, 1, TRUE),
2550: array(2034, 3, 20, 2, FALSE),
2551: );
2552:
2553: //案を選ぶ
2554: switch ($method) {
2555: case 1:
2556: $table = $table01;
2557: break;
2558: case 2:
2559: $table = $table02;
2560: break;
2561: case 3:
2562: $table = $table03;
2563: break;
2564: //何もしない
2565: default:
2566: return;
2567: }
2568:
2569: foreach ($this->tblmoon as $key=>$arr) {
2570: if (($arr['year'] == 2033) && ($arr['month'] >= 7)) {
2571: $this->tblmoon[$key]['day'] = $table[$arr['month'] - 7][2];
2572: $this->tblmoon[$key]['oldmonth'] = $table[$arr['month'] - 7][3];
2573: $this->tblmoon[$key]['oldleap'] = $table[$arr['month'] - 7][4];
2574: $this->tblmoon[$key]['jd'] = $this->Gregorian2JD($this->tblmoon[$key]['year'], $this->tblmoon[$key]['month'], $this->tblmoon[$key]['day'], 0, 0, 0);
2575: } else if (($arr['year'] == 2034) && ($arr['month'] <= 3)) {
2576: $this->tblmoon[$key]['day'] = $table[$arr['month'] + 5][2];
2577: $this->tblmoon[$key]['oldmonth'] = $table[$arr['month'] + 5][3];
2578: $this->tblmoon[$key]['oldleap'] = $table[$arr['month'] + 5][4];
2579: $this->tblmoon[$key]['jd'] = $this->Gregorian2JD($this->tblmoon[$key]['year'], $this->tblmoon[$key]['month'], $this->tblmoon[$key]['day'], 0, 0, 0);
2580: }
2581: }
2582: }
方法は、上述の表をあらかじめ用意しておき、$tblmoon の内容を置換するものである。

天保暦は、公式には、天保15年1月1日(1844年2月18日)から明治5年12月2日(1872年12月31日)までの約29年しか使われていない。にもかかわらず、その後、150年近くにわたり「旧暦」としてカレンダーに載っている。
旧暦計算のコードをご覧になれば分かるとおり、じつに複雑で計算コストがかかる。
じつは、旧暦の平均太陽年は現在の太陽暦(グレゴリオ暦)より誤差が小さい。にもかかわらずグレゴリオ暦が普及したのは、その算出方法がシンプルだからだろう。
解説:干支と十二支の計算
pahooCalendar.php
2644: /**
2645: * 十干の基準値$a1と十二支の基準値$a2から干支を求める.
2646: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_eto
2647: * @param int $a1 十干の基準値
2648: * @param int $a2 十二支の基準値
2649: * @param int $n 計算したい値
2650: * @return string 干支
2651: */
2652: function __eto($a1, $a2, $n) {
2653: //十干
2654: static $table1 = array(
2655: 0 =>'甲',
2656: 1 =>'乙',
2657: 2 =>'丙',
2658: 3 =>'丁',
2659: 4 =>'戊',
2660: 5 =>'己',
2661: 6 =>'庚',
2662: 7 =>'辛',
2663: 8 =>'壬',
2664: 9 =>'癸'
2665: );
2666:
2667: //十二支
2668: static $table2 = array(
2669: 0 =>'子',
2670: 1 =>'丑',
2671: 2 =>'寅',
2672: 3 =>'卯',
2673: 4 =>'辰',
2674: 5 =>'巳',
2675: 6 =>'午',
2676: 7 =>'未',
2677: 8 =>'申',
2678: 9 =>'酉',
2679: 10 =>'戌',
2680: 11 =>'亥'
2681: );
2682:
2683: return $table1[abs($n - $a1) % 10] . $table2[abs($n - $a2) % 12];
2684: }
干支は、甲・乙・丙・丁・戊・己・庚・辛・壬・癸の10要素からなる十干と、子・丑・寅・卯・辰・巳・午・未・申・酉・戌・亥の12要素からなる十二支の組み合わせからなる。
つまり、十干は年/月/日が10回ごとに繰り返され、十二支は年/月/日が12回ごとに繰り返されることになる。これを計算するのが __eto である。

次に、基準となる年月日を調べておく。
甲の年は西暦1904年(明治37年)、子の年は西暦1900年(明治33年)である。年の干支は、この2つを基準に計算する。
甲子の月は1903年(明治36年)11月である。月の干支は、ここを基準に計算する。
甲子の日は1902年(明治35年)4月11日である。日の干支は、ここを基準に計算する。

ちなみに、干支も十二支も古代中国で考え出されたものだが、十二支の方は、木星が黄道を1周するのがほぼ12年(公転周期11.86年)ということに対応している。古代中国では木星を暦に関わる重要な天体と位置づけており、歳星という名で呼ばれていた。
解説:土用の判定
pahooCalendar.php
1293: /**
1294: * 指定した年月日が土用かどうかを求める.
1295: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_isDoyo
1296: * @param int $year, $month, $day グレゴリオ暦による年月日
1297: * @return array(季節, 種類)
1298: */
1299: function isDoyo($year, $month, $day) {
1300: static $table1 = array('冬' ,'春', '夏', '秋');
1301: static $table2 = array('in'=>'入り', 'ushi'=>'丑', 'ushi2'=>'丑', 'out'=>'明け');
1302: static $year0 = -1; //西暦年保存用
1303: static $doyo = array(); //土用情報保存用
1304:
1305: //土用情報を取得
1306: if ($year0 != $year) {
1307: $year0 = $year;
1308: $doyo = $this->getDoyo($year0);
1309: }
1310:
1311: //土用判定
1312: foreach ($doyo as $key1=>$arr1) {
1313: foreach ($arr1 as $key2=>$arr2) {
1314: if (($arr2['year'] == $year0) && ($arr2['month'] == $month) && ($arr2['day'] == $day)) {
1315: return array($table1[$key1], $table2[$key2]);
1316: }
1317: }
1318: }
1319: return array('', '');
1320: }

isDoyo メソッドは、まず、「PHPで土用を求める」で作った getDoyo メソッドを呼び出し、その年の土用に関する情報をstatic配列 $doyo にストックしておく。計算量を減らす目的で、次に呼び出されたときも同じ年なら、この配列 $doyo を参照する。

引数として与えられた年月日が土用の入り、明け、丑の日であるかどうか、この配列 $doyo をスキャンして判定する。
解説:彼岸の計算
pahooCalendar.php
1322: /**
1323: * 指定した年の彼岸を求める.
1324: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_getHigan * @param int $year 西暦年
1325: * @return array [0]['in']['year','month','day'] 春の彼岸入り
1326: * ['out']['year','month','day'] 春の彼岸明け
1327: * [1] 秋の土用の入り/明け
1328: */
1329: function getHigan($year) {
1330: static $higan = array(); //彼岸情報保存用
1331:
1332: //春の彼岸
1333: $day = $this->getVernalEquinox($year);
1334: $higan[0]['in']['year'] = (int)$year;
1335: $higan[0]['in']['month'] = (int)3;
1336: $higan[0]['in']['day'] = (int)($day - 3);
1337: $higan[0]['out']['year'] = (int)$year;
1338: $higan[0]['out']['month'] = (int)3;
1339: $higan[0]['out']['day'] = (int)($day + 3);
1340:
1341: //秋の彼岸
1342: $day = $this->getAutumnalEquinox($year);
1343: $higan[1]['in']['year'] = (int)$year;
1344: $higan[1]['in']['month'] = (int)9;
1345: $higan[1]['in']['day'] = (int)($day - 3);
1346: $higan[1]['out']['year'] = (int)$year;
1347: $higan[1]['out']['month'] = (int)9;
1348: $higan[1]['out']['day'] = (int)($day + 3);
1349:
1350: return $higan;
1351: }

彼岸入り、明けの求め方については、その年の彼岸を求める getHigan メソッドを用意した。カレンダー計算の冒頭で実行する。
まず、getVernalEquinox メソッドで春分の日を求め、そこから3日前を彼岸入りに、3日後を彼岸明けとして登録する。
秋の彼岸については、getAutumnalEquinox メソッドで秋分の日を求め、同様に登録する。
解説:雑節の計算
pahooCalendar.php
1353: /**
1354: * 指定した年の雑節を求める.
1355: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_getZassetsu
1356: * @param int $year 西暦年
1357: * @return array [雑節]['year','month','day']
1358: * 雑節‥‥社日,八十八夜,入梅,二百十日,二百二十日
1359: * 次の雑節は個別のメソッドを利用する
1360: * 節分→ isSetsubun()
1361: * 彼岸→ getHigan()
1362: * 半夏生→ getSolarTerm72()
1363: * 土用→isDoyo()
1364: */
1365: function getZassetsu($year) {
1366: static $zassetsu = array(); //雑節情報保存用
1367:
1368: //社日計算テーブル
1369: static $table_sha = array(
1370: '甲' => +4,
1371: '乙' => +3,
1372: '丙' => +2,
1373: '丁' => +1,
1374: '戊' => 0,
1375: '己' => -1,
1376: '庚' => -2,
1377: '辛' => -3,
1378: '壬' => -4,
1379: );
1380:
1381: //春社を求める
1382: $label = '春社';
1383: $day = $this->getVernalEquinox($year); //春分の日
1384: $month = 3;
1385:
1386: $eto = $this->eto_day($year, $month, $day);
1387: //癸の日の場合
1388: if (preg_match('/癸/ui', $eto) > 0) {
1389: $zassetsu[$label]['year'] = $year;
1390: $zassetsu[$label]['month'] = $month;
1391: $l1 = $this->longitude_sun($year, $month, $day, 12, 0, 0);
1392: //春分が午前中なら前の戊の日
1393: if (($l1 < 0) || ($l1 >= 360)) {
1394: $zassetsu[$label]['day'] = $day - 5;
1395: //春分が午後なら前の戊の日
1396: } else {
1397: $zassetsu[$label]['day'] = $day + 5;
1398: }
1399: //それ以外の場合
1400: } else {
1401: foreach ($table_sha as $key=>$val) {
1402: if (preg_match('/' . $key . '/ui', $eto) > 0) {
1403: $zassetsu[$label]['year'] = $year;
1404: $zassetsu[$label]['month'] = $month;
1405: $zassetsu[$label]['day'] = $day + $val;
1406: break;
1407: }
1408: }
1409: }
1410:
1411: //秋社を求める
1412: $label = '秋社';
1413: $day = $this->getAutumnalEquinox($year); //秋分の日
1414: $month = 9;
1415: $eto = $this->eto_day($year, $month, $day);
1416: //癸の日の場合
1417: if (preg_match('/癸/ui', $eto) > 0) {
1418: $zassetsu[$label]['year'] = $year;
1419: $zassetsu[$label]['month'] = $month;
1420: $l1 = $this->longitude_sun($year, $month, $day, 12, 0, 0);
1421: //秋分が午前中なら前の戊の日
1422: if ($l1 <= 180) {
1423: $zassetsu[$label]['day'] = $day - 5;
1424: //秋分が午後なら前の戊の日
1425: } else {
1426: $zassetsu[$label]['day'] = $day + 5;
1427: }
1428: //それ以外の場合
1429: } else {
1430: foreach ($table_sha as $key=>$val) {
1431: if (preg_match('/' . $key . '/ui', $eto) > 0) {
1432: $zassetsu[$label]['year'] = $year;
1433: $zassetsu[$label]['month'] = $month;
1434: $zassetsu[$label]['day'] = $day + $val;
1435: break;
1436: }
1437: }
1438: }
1439:
1440: //立春を求める
1441: $month = 2;
1442: $day = 1;
1443: while ($day < 10) {
1444: if ($this->getSolarTerm($year, $month, $day) == '立春') break;
1445: $day++;
1446: }
1447: $ve = $this->AD2JD($year, $month, $day, 0, 0, 0);
1448:
1449: //八十八夜
1450: $label = '八十八夜';
1451: list($zassetsu[$label]['year'], $zassetsu[$label]['month'], $zassetsu[$label]['day']) = $this->JD2Gregorian($ve + 87);
1452:
1453: //入梅
1454: $label = '入梅';
1455: $month = 6;
1456: $day = 1;
1457: while ($day < 30) {
1458: //太陽黄経
1459: $l2 = $this->longitude_sun($year, $month, $day, 24, 0, 0);
1460: if ($l2 >= 80) {
1461: $zassetsu[$label]['year'] = $year;
1462: $zassetsu[$label]['month'] = $month;
1463: $zassetsu[$label]['day'] = $day;
1464: break;
1465: }
1466: $day++;
1467: }
1468:
1469: //二百十日
1470: $label = '二百十日';
1471: list($zassetsu[$label]['year'], $zassetsu[$label]['month'], $zassetsu[$label]['day']) = $this->JD2Gregorian($ve + 209);
1472:
1473: //二百二十日
1474: $label = '二百二十日';
1475: list($zassetsu[$label]['year'], $zassetsu[$label]['month'], $zassetsu[$label]['day']) = $this->JD2Gregorian($ve + 219);
1476:
1477: return $zassetsu;
1478: }
ここでは、残る社日、八十八夜、入梅、二百十日、二百二十日の求め方を紹介する。

社日は、産土神を祀る日で、春・秋の2回ある。春のものを春社、秋のものを秋社と呼ぶ。
春分に最も近い戊の日が社日となる。ただし戊と戊のちょうど中間、つまり癸の日が秋分の日に重なる場合は、春分の瞬間が午前中ならば前の戊の日、午後ならば後の戊の日とする。
秋分の日についても同様にして求める。

入梅は太陽黄経が80度の日である。

立春を第1日目として、八十八夜は88日目、二百十日は210日目、二百二十日は220日目を、それぞれ指す。

これらの雑節を求めるのが getZassetsu メソッドである。カレンダー計算の冒頭で実行する。
上記で説明した雑節の求め方をプログラムに実装した。
解説:一粒万倍日
1685年(貞享2年)に渋川春海が編纂した貞享暦から外されたが、近年、宝くじを買うのに良い日と宣伝され、再び脚光を浴びるようになった。

一粒万倍日は、節月と日の干支の組み合わせで決まる。
組み合わせ(計算方式)は2つあり、下表に整理する。
節月 | 二十四節気 | 計算方式I | 計算方式II |
---|---|---|---|
1 | 立春~啓蟄 | 丑・午 | 酉 |
2 | 啓蟄~清明 | 酉・寅 | 申 |
3 | 清明~立夏 | 子・卯 | 未 |
4 | 立夏~芒種 | 卯・辰 | 午 |
5 | 芒種~小暑 | 巳・午 | 巳 |
6 | 小暑~立秋 | 酉・午 | 辰 |
7 | 立秋~白露 | 子・未 | 卯 |
8 | 白露~寒露 | 卯・申 | 寅 |
9 | 寒露~立冬 | 酉・午 | 丑 |
10 | 立冬~大雪 | 酉・戌 | 子 |
11 | 大雪~小寒 | 亥・子 | 亥 |
12 | 小寒~立春 | 卯・子 | 戌 |
pahooCalendar.php
1055: /**
1056: * 指定した年月日の節月を求める.
1057: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-42-01.shtm
1058: * @param int $year, $month, $day グレゴリオ暦による年月日
1059: * @return int 節月/0:計算失敗
1060: */
1061: function getSetsugetsu($year, $month, $day) {
1062: static $table = array(
1063: 1 => 315,
1064: 2 => 345,
1065: 3 => 15,
1066: 4 => 45,
1067: 5 => 75,
1068: 6 => 105,
1069: 7 => 135,
1070: 8 => 165,
1071: 9 => 195,
1072: 10 => 225,
1073: 11 => 255,
1074: 12 => 285,
1075: 13 => 315
1076: );
1077:
1078: //太陽黄経
1079: $ls = $this->longitude_sun($year, $month, $day, 24, 0, 0);
1080:
1081: //節月
1082: foreach ($table as $key=>$val) {
1083: if ($key == 2) {
1084: if (($ls >= $table[2]) || ($ls < $table[3])) return $key;
1085: } else {
1086: if (($ls >= $table[$key]) && ($ls < $table[$key + 1])) return $key;
1087: }
1088: }
1089: return 0;
1090: }
pahooCalendar.php
2721: /**
2722: * 指定した年月日が一粒万倍日かどうかを求める.
2723: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_ichiryumanbai
2724: * @param int $year, $month, $day 年月日(グレゴリオ暦)
2725: * @param int $method 計算方式(1または2)(省略可能:デフォルトは1)
2726: * @return bool TRUE:一粒万倍日/FALSE:ではない
2727: */
2728: function ichiryumanbai($year, $month, $day, $method=1) {
2729: //計算方式I
2730: $table[1] = array(
2731: 1 => array('丑', '午'),
2732: 2 => array('酉', '寅'),
2733: 3 => array('子', '卯'),
2734: 4 => array('卯', '辰'),
2735: 5 => array('巳', '午'),
2736: 6 => array('酉', '午'),
2737: 7 => array('子', '未'),
2738: 8 => array('卯', '申'),
2739: 9 => array('酉', '午'),
2740: 10 => array('酉', '戌'),
2741: 11 => array('亥', '子'),
2742: 12 => array('卯', '子'),
2743: );
2744: //計算方式II
2745: $table[2] = array(
2746: 1 => array('酉'),
2747: 2 => array('申'),
2748: 3 => array('未'),
2749: 4 => array('午'),
2750: 5 => array('巳'),
2751: 6 => array('辰'),
2752: 7 => array('卯'),
2753: 8 => array('寅'),
2754: 9 => array('丑'),
2755: 10 => array('子'),
2756: 11 => array('亥'),
2757: 12 => array('戌'),
2758: );
2759:
2760: //計算方式のチェック
2761: if (($method != 1) && ($method != 2)) return FALSE;
2762:
2763: //節月を求める
2764: $setsu = $this->getSetsugetsu($year, $month, $day);
2765: //干支の右1文字取得
2766: $eto = mb_substr($this->eto_day($year, $month, $day), 1, 1);
2767:
2768: return in_array($eto, $table[$method][$setsu]);
2769: }
解説:天赦日
- 立春から立夏の前日までの戊寅の日。
- 立夏から立秋の前日までの甲午の日。
- 立秋から立冬の前日までの戊申の日。
- 立冬から立春の前日までの甲子の日。
pahooCalendar.php
2771: /**
2772: * 指定した年月日が天赦日かどうかを求める.
2773: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_tenshanichi
2774: * @param int $year, $month, $day 年月日(グレゴリオ暦)
2775: * @return bool TRUE:天赦日/FALSE:ではない
2776: */
2777: function tenshanichi($year, $month, $day) {
2778: $table = array(
2779: array('戊寅', -45, 45),
2780: array('甲午', 45, 135),
2781: array('戊申', 135, 225),
2782: array('甲子', 225, 315)
2783: );
2784:
2785: $ret = FALSE;
2786: $eto = $this->eto_day($year, $month, $day);
2787: foreach ($table as $item) {
2788: if ($item[0] == $eto) {
2789: $longitude = $this->longitude_sun($year, $month, $day, 0, 0, 0);
2790: if ($longitude >= 315) $longitude -= 360;
2791: if (($longitude >= $item[1]) && ($longitude <= $item[2])) {
2792: $ret = TRUE;
2793: break;
2794: }
2795: }
2796: }
2797: return $ret;
2798: }
もし合致したら、次に longitude_sun により太陽黄経を求め、天赦日定義 $table の範囲内にあるかどうかを調べる。
解説:カレンダー作成
tripleCalendar.php
186: /**
187: * 1ヶ月分のカレンダーを作成
188: * @param object $pcl pahooCalendarオブジェクト
189: * @param int $start 週の開始曜日(0:日曜日, 1:月曜日...6:土曜日)
190: * @param int $year 西暦年
191: * @param int $month 月
192: * @return string HTMLコンテンツ/FALSE:エラー
193: */
194: function makeCalendar($pcl, $start, $year, $month) {
195: //雑節テーブル
196: $table_za = array('春社', '秋社', '八十八夜', '入梅', '二百十日', '二百二十日');
197:
198: //月のエラーチェック
199: if ($month < 1 && $month > 12) return FALSE;
200:
201: $eto_year = $pcl->eto_year($year);
202: $eto_month = $pcl->eto_month($year, $month);
203:
204: //彼岸
205: $higan = $pcl->getHigan($year);
206: //雑節
207: $zassetsu = $pcl->getZassetsu($year);
208:
209: $html =<<< EOT
210: <table class="calendar">
211: <tr>
212: <th colspan="7"><span class="large">{$year}年({$eto_year}) {$month}月({$eto_month})</span></th>
213: </tr>
214: <tr>
215:
216: EOT;
217:
218: //曜日の行
219: for ($i = 0; $i < 7; $i++) {
220: $n = ($start + $i) % 7;
221: if ($n == 6) $class = 'blue';
222: else if ($n == 0) $class = 'red';
223: else $class = 'black';
224: $str = $pcl->__getWeekString($n);
225: $html .= "<th><span class=\"{$class}\">{$str}</span></th>";
226: }
227: $html .= "</tr>\n";
228:
229: //カレンダー本体
230: $wn1 = $pcl->getWeekNumber($year, $month, 1); //月の最初の曜日
231: $dim = $pcl->getDaysInMonth($year, $month); //月の最後の日
232: $cnt = 0;
233: $flag = FALSE;
234: $n = $start;
235: $day = 1;
236: while (1) {
237: if ($cnt % 7 == 0) $html .= "<tr>\n";
238: //曜日の色
239: if ($n % 7 == 6) $class = 'blue';
240: else if ($n % 7 == 0) $class = 'red';
241: else $class = 'black';
242: if ($n % 7 == $wn1) $flag = TRUE;
243: //表示開始
244: if ($flag) {
245: $ss = '';
246: //祝日
247: $holiday = $pcl->getHoliday($year, $month, $day);
248: if ($holiday != '') {
249: $class = 'red';
250: $ss .= "<span class=\"small red\">{$holiday}<br></span>\n";
251: }
252: //二十四節気
253: $solarterm = $pcl->getSolarTerm($year, $month, $day);
254: //土用
255: list($ss1, $ss2) = $pcl->isDoyo($year, $month, $day);
256: if ($ss2 == '明け') {
257: $ss2 = '';
258: } else if (($ss1 != '夏') && ($ss2 == '丑')) {
259: $ss2 = '';
260: }
261: if ($ss1 != '' && $ss2 != '') {
262: if ($solarterm != '') {
263: $solarterm .= '<br>土用の' . $ss2;
264: } else {
265: $solarterm = '土用の' . $ss2;
266: }
267: }
268: if ($solarterm != '') {
269: $ss .= "<span class=\"small\">{$solarterm}<br></span>\n";
270: }
271: //七十二候
272: $solarterm72 = $pcl->getSolarTerm72($year, $month, $day);
273: if ($solarterm72 != '') {
274: $ss .= "<span class=\"small\">{$solarterm72}<br></span>\n";
275: }
276: //彼岸
277: if (($higan[0]['in']['month'] == $month) && ($higan[0]['in']['day'] == $day)) {
278: $solarterm = '彼岸入り';
279: $ss .= "<span class=\"small\">彼岸入り<br></span>\n";
280: } else if (($higan[0]['out']['month'] == $month) && ($higan[0]['out']['day'] == $day)) {
281: $solarterm = '彼岸明け';
282: $ss .= "<span class=\"small\">彼岸明け<br></span>\n";
283: } else if (($higan[1]['in']['month'] == $month) && ($higan[1]['in']['day'] == $day)) {
284: $solarterm = '彼岸入り';
285: $ss .= "<span class=\"small\">彼岸入り<br></span>\n";
286: } else if (($higan[1]['out']['month'] == $month) && ($higan[1]['out']['day'] == $day)) {
287: $solarterm = '彼岸明け';
288: $ss .= "<span class=\"small\">彼岸明け<br></span>\n";
289: }
290: //雑節
291: foreach ($table_za as $label) {
292: if (($zassetsu[$label]['month'] == $month) && ($zassetsu[$label]['day'] == $day)) {
293: $solarterm = $label;
294: $ss .= "<span class=\"small\">{$label}<br></span>\n";
295: }
296: }
297: //一粒万倍日
298: $manbai = $pcl->ichiryumanbai($year, $month, $day, 1) ? '一粒万倍日' : '';
299: if ($manbai != '') {
300: $ss .= "<span class=\"small\">{$manbai}<br></span>\n";
301: }
302: //天赦日
303: $tensha = $pcl->tenshanichi($year, $month, $day) ? '天赦日' : '';
304: if ($tensha != '') {
305: $ss .= "<span class=\"small\">{$tensha}<br></span>\n";
306: $tensha = $tensha . '<br>';
307: }
308: //旧暦
309: list($oldmonth, $oldday, $oldleap) = $pcl->Gregorian2Lunar($year, $month, $day);
310: //旧暦テーブルの再作成
311: if ($pcl->error && ($pcl->resolve2033 > 0)) {
312: $pcl->error = FALSE;
313: $pcl->errmsg = '';
314: $yy = ($month <= 2) ? $year - 1 : $year;
315: $pcl->makeLunarCalendar($yy, RESOLVE2033);
316: list($oldmonth, $oldday, $oldleap) = $pcl->Gregorian2Lunar($year, $month, $day);
317: }
318: //旧暦作成
319: if (! $pcl->error) {
320: $oldleap = $oldleap ? '閏' : '';
321: $rokuyou = $pcl->rokuyou($oldmonth, $oldday);
322: $oldcal = sprintf('%s%d月%d日<br>(%s)', $oldleap, $oldmonth, $oldday, $rokuyou);
323: //旧暦作成不可(2033年問題)
324: } else {
325: $oldcal = '';
326: }
327: //日の干支
328: $eto_day = $pcl->eto_day($year, $month, $day);
329:
330: //表示
331: $html .=<<< EOT
332: <td>
333: <span class="large {$class}">{$day}</span>
334: <div class="narrow">
335: <span class="small red">{$holiday}</span><br>
336: <span class="small blue">{$tensha}{$manbai}</span><br>
337: <span class="small">{$solarterm}</span><br>
338: <span class="small">{$solarterm72}</span><br>
339: <span class="small">{$eto_day}</span><br>
340: <span class="small">{$oldcal}</span>
341: </div>
342: </td>
343:
344: EOT;
345: $day++;
346: if ($day > $dim) break;
347: } else {
348: $html .= "<td> </td>";
349: }
350: $cnt++;
351: $n++;
352: if ($cnt % 7 == 0) $html .= "</tr>\n";
353: }
354: //最後の日以降の処理
355: $cnt++;
356: while ($cnt % 7 != 0) {
357: $html .= "<td> </td>";
358: $cnt++;
359: if ($cnt % 7 == 0) $html .= "</tr>\n";
360: }
361:
362: $html .= "</table>\n";
363:
364: return $html;
365: }
週の開始曜日を自由に設定できるようにするための工夫をしている。

カレンダー本体を作成する処理では、まず、月の最初の曜日 $wn1 と、月の最後の日 $dim を計算しておく。
$wn1 と週の開始曜日 $start が一致するまでは変数 $flag がFALSEのままで、この時は日付を入れずに空のままにしておく。
$flag がTRUEになったら日付を入れてゆく。あわせて、二十四節気、旧暦の計算を行う。
旧暦は前述のメソッド Gregorian2Lunar を呼び出すが、旧暦変換テーブルがみつからないときは、再びメソッド makeLunarCalendar を呼び出して旧暦変換テーブルを追加作成する。
土用の判定については、四季の土用の入りと丑の日のみを表示するようにしている。土用の明けは、立春、立夏、立秋、立冬の前日であるから、二十四節気の表示からわかるからだ。
$dim に達したらループを抜け出し、行末まで空白のセルを追加してゆく。
解説:メインプログラム
tripleCalendar.php
505: // メイン・プログラム =======================================================
506: //パラメータ
507: //西暦年
508: $errmsg = '';
509: $year = getValidNumber('year', $errmsg, date('Y'), TRUE, YEAR_MIN, YEAR_MAX);
510: if ($errmsg != '') {
511: $year = date('Y');
512: $errmsg = '';
513: }
514: //月
515: $month = getValidNumber('month', $errmsg, date('n'), TRUE, 1, 12);
516: if ($errmsg != '') {
517: $month = date('n');
518: $errmsg = '';
519: }
520: //週の開始曜日
521: $start = getValidNumber('start', $errmsg, 0, TRUE, 0, 6);
522: if ($errmsg != '') {
523: $start = 0;
524: $errmsg = '';
525: }
526: //カレンダー作成期間(ヶ月)
527: $period = getValidNumber('period', $errmsg, PERIOD_DEF, TRUE, PERIOD_MIN, PERIOD_MAX);
528: if ($errmsg != '') {
529: $period = 3;
530: $errmsg = '';
531: }
532: //表示モード
533: $mode = getValidNumber('mode', $errmsg, 0, TRUE, 0, 1);
534: if ($errmsg != '') {
535: $mode = 0;
536: $errmsg = '';
537: }
538: $msg = '';
539:
540: //暦計算に関わるクラス
541: $pcl = new pahooCalendar(LANGUAGE, UTCDIFF);
542:
543: //表示用HTMLを生成する.
544: $HtmlBody = makeCommonBody($mode, $pcl, $year, $month, $start, $period, $msg);
545:
546: //画面に表示する.
547: echo $HtmlHeader;
548: echo $HtmlBody;
549: echo $HtmlFooter;
コマンドラインまたはURL変数で、カレンダー作成開始する西暦年(year)、月(month)、週の開始曜日(start;0:日曜日, 1:月曜日...6:土曜日)、作成期間(period、ヶ月)、表示モード(mode;0:全部表示,1:カレンダーのみ)を指定できる。万年カレンダーと言いながら、太陽や月の位置計算の精度の関係で、計算可能な範囲を100年間に絞っている😓
なお、入力可能な西暦年の範囲は2000以上2099以下の整数、月の範囲は1以上12以下の整数、週の開始曜日は0以上6以下の整数、カレンダー作成期間は1以上36以下の整数、表示モードは0以上1以下の整数に、それぞれ制約した。この範囲を超えたり、数字以外の入力があった場合はエラー処理は行わず、強制的に現在年月、週の開始曜日を0(日曜日)、週の開始曜日を0,表示モードを0にセットする。
質疑応答
「PHPで3ヶ月カレンダーを作る」のページのソースなのですが「サンプル・プログラムの解説:カレンダー作成」のソースの0171行目に「<tr>」の開始タグを入れたほうがいいと思います。曜日部分の行部分TRの開始タグが無いようです。【回答】
間違えであればすいません。
ご指摘ありがとうございます。<tr> タグが抜けていました。追加しました。
活用例
参考サイト
- PHPで祝日を求める:ぱふぅ家のホームページ
- PHPで二十四節気一覧を作成:ぱふぅ家のホームページ
- PHPで土用を求める:ぱふぅ家のホームページ
- PHPセキュリティ対策:数値入力とバリデーション:ぱふぅ家のホームページ
- 旧暦と六曜を作りましょう:こよみのページ
- 旧暦2033年問題について:国立天文台暦計算室
- 2033年旧暦閏月問題の見解:日本カレンダー暦文化振興協会
- 七十二候:今日は何の日~毎日が記念日~
- 旧暦2033年問題:Oka Laboratory 備忘録
- 旧暦六曜Javaソースプログラム公開:がらくた研究室
- 「月の名前」の計算方法:ここですという名前のブログやさん
- 二十四節気・七十二候・干支・旧暦・六曜カレンダー:みんなの知識 ちょっと便利帳
- 歴代天皇の誕生日が祝日に!?:みんなの知識 ちょっと便利帳
- 一粒万倍日を調べる〈タイプ1〉:みんなの知識 ちょっと便利帳
参考書籍
![]() |
知れば知るほど面白い暦の謎 | ||
著者 | 片山 真人 | ||
出版社 | 三笠書房 | ||
サイズ | 文庫 | ||
発売日 | 2022年02月17日頃 | ||
価格 | 858円(税込) | ||
ISBN | 9784837987635 | ||
1年、1カ月、1週間、1日…… 時の体系「暦」は、あまりに身近な存在で、私たちの生活に不可欠なもの。 でも、よくよく考えてみたら、素朴な疑問が湧いてきます。 1年は、なぜ「365日」なのか? 1週間は、なぜ「7日」なのか? 「曜日」は、どのように生まれたのか? 「季節」は、なぜ変化するのか? 1日は、なぜ「24時間」なのか?-- そこで本書では、国立天文台「暦の専門家」片山真人先生が、 「暦の謎」についてわかりやすく解き明かします。 1年、1カ月、1週間、1日、1時間、閏年、閏秒……といった暦の構成要素から、 潮の満ち干、日食・月食といった現象まで、暦の奥深い世界が楽しめる1冊です。 | |||
「PHPで祝日を求める」「PHPで二十四節気一覧を作成」に、雑節や七十二候、旧暦、六曜、干支、一粒万倍日の計算を加えた。
(2023年10月6日)makeCalendar() 祝日の日付が赤くなるよう修正
(2023年2月11日)getSolarTerm72() 表記改訂:水澤腹堅→水沢腹堅
(2023年2月4日)表記改訂:七十二候
(2023年1月14日)天赦日を追加
(2023年1月5日)2023年2月の旧暦表示の不具合を修正‥‥pahooCalendar::makeLunarCalendar() で朔を求める方式を修正した.