目次
サンプル・プログラムの実行例
サンプル・プログラム
| supermoon.php | サンプル・プログラム本体。 |
| pahooCalendar.php | 暦・潮位計算クラス pahooCalendar。 暦・潮位計算クラスの使い方は「PHPで二十四節気・七十二候一覧を作成」「PHPで月齢を計算」「PHPで日出没・月出没・月齢・潮を計算」「PHPで潮位を計算する」などを参照。include_path が通ったディレクトリに配置すること。 |
| pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 1.5.0 | 2023/01/14 | 数値入力にSpinner、pahooInputData導入 |
| 1.4.0 | 2023/01/09 | pahooCalendarクラスの計算精度を向上 |
| 1.3.0 | 2021/01/04 | 満月の日を取得するアルゴリズムを見直した |
| 1.2 | 2021/01/04 | PHP8対応,満月の呼び名等を追加 |
| 1.1 | 2018/01/03 | 明るさの比などを一覧表示 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 4.6.1 | 2025/11/23 | next_fullmoon: bug-fix |
| 4.6.0 | 2025/10/08 | getMidAutumnMoon() 追加 |
| 4.5.1 | 2025/05/31 | deg2ddmm(), deg2hhmm() 不具合修正 |
| 4.5.0 | 2024/03/17 | ヒジュラ暦メソッドを追加 |
| 4.4.1 | 2024/03/17 | getCabinetOfficeHolidayTable() -- bug-fix |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 2.0.1 | 2025/08/11 | getParam() bug-fix |
| 2.0.0 | 2025/08/11 | pahooLoadEnv() 追加 |
| 1.9.0 | 2025/07/26 | getParam() 引数に$trim追加 |
| 1.8.1 | 2025/03/15 | validRegexPattern() debug |
| 1.8.0 | 2024/11/12 | validRegexPattern() 追加 |
準備:pahooInputData 関数群
また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。
準備:pahooCalendar クラス
pahooCalendar.php
11: class pahooCalendar {
12: var $CONVERGE = 0.00005; // 逐次近似計算収束判定値
13: var $ASTRO_REFRACT = 0.585556; // 大気差
14: var $TDIFF = +9.0; // 世界時との時差
15: var $error, $errmsg; // エラーフラグ,エラーメッセージ
16: var $year, $month, $day; // 西暦年月日
17: var $tblmoon; // グレゴリオ暦=旧暦テーブル
18: var $language; // 表示言語(jp:日本語, en:英語, en3:英語略記)
19: var $resolve2033; // 旧暦2033年問題解決案 0:解決しない,1:案1,2:案2,3:対応案3 → https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_resolveLunarCalendar2033
20: var $pcc; // pahooCacheインスタンス
21: var $CabinetOfficeHolidayTables; // 内閣府が公開している祝日表
22: const CABINETOFFICE_HOLIDAY_FILE = 'https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv'; // 内閣府が公開している祝日表URL
23:
24: /**
25: * コンストラクタ
26: * @param string $language 表示言語;省略時 jp
27: * @param float $tdiff 世界時との時差(省略時 +9.0;日本標準時)
28: * @param object $pcc pahooCacheインスタンス;省略時 NULL
29: * インターネット経由で内閣府の国民の祝日を参照するときに指定
30: * @return bool オブジェクト/FALSE:$tdiffが不正
31: */
32: function __construct($language='jp', $tdiff=+9.0, $pcc=NULL) {
33: $this->error = FALSE;
34: $this->errmsg = '';
35: $this->year = date('Y');
36: $this->month = date('n');
37: $this->day = date('j');
38: $this->resolve2033 = 0;
39: $this->pcc = $pcc;
40: $this->CabinetOfficeHolidayTables = array();
41:
42: $this->setLanguage($language);
43: if ($this->setTimeDifference($tdiff) == FALSE) {
44: $this->error = TRUE;
45: $this->errmsg = 'illegal tdiff';
46: }
47: }
準備:初期値など
supermoon.php
55: // 各種定数(START) ===========================================================
56:
57: // 指定できる西暦年の範囲
58: define('MIN_YEAR', 1901);
59: define('MAX_YEAR', 2099);
60:
61: // 表示言語(jp:日本語, en:英語, en3:英語略記)
62: define('LANGUAGE', 'jp');
63:
64: // 世界時からの時差(日本標準時)
65: define('UTCDIFF', +9.0);
66:
67: // 計算期間(月)
68: define('CALC_TERM', 12);
69:
70: // 視半径が最小/最大の時の背景色
71: define('MIN_COLOR', '88EEFF');
72: define('MAX_COLOR', 'FFEE88');
73:
74: // Spinner - jQuery UI を使用するかどうか
75: define('USESPINNER', TRUE);
76:
77: // 数値増減クリックで即判定するかどうか(TRUE:即判定,FALE:判定ボタンを用意)
78: define('ONCHANGE', FALSE);
79:
80: // 表示幅(単位:ピクセル)
81: define('WIDTH', 600);
82:
83: // 各種定数(END) ===============================================================
月齢、月の視半径、各種カレンダー計算は、ユーザークラス "pahooCalendar" に用意したメソッド群を利用する。
オブジェクト生成時に、表示言語として "ja"(日本語)を、世界時との時差としてユーザー定義の定数 UTCDIFF を渡しておく。こうすることで、pahooCalendar クラスが出力する文字列は日本語に、日時計算は時差 UTCDIFF がある前提で計算を行う。
数値入力に jQuery UI の Spinner を使用している。設定でOFFにすることもできる。Spinner の使い方については、「Spinner - jQuery UI - PHPで素数かどうか判定」をご覧いただきたい。
準備:次の満月の日時を求める
一方、月齢は朔の日(新月の日)を第1日とする日数であるから、月齢15が必ずしも満月の日になるとは限らない。
pahooCalendar.php
1898: /**
1899: * 指定した日時の次の満月の日時を求める(日時はローカル時間).
1900: * 太陽と月の黄緯差180度になる日時を近似計算で求める.
1901: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-50-01.shtm
1902: * @param int $year, $month, $day 年月日(グレゴリオ暦)
1903: * @param float $hour, $min, $sec 時分秒(ローカル時間)
1904: * @param float $tdiff UTCとの時差;NULLの時はTDIFF参照
1905: * @return array($year, $month, $day, $hour, $min, $sec) 日時(ローカル時間)
1906: */
1907: function next_fullmoon($year, $month, $day, $hour, $min, $sec, $tdiff=NULL) {
1908: $dif = 29.55; // 一朔望月(近似計算の指標)
1909: $jd = $this->Gregorian2JD($year, $month, $day, $hour, $min, $sec, $tdiff);
1910: $jdc = (float)$jd;
1911:
1912: // ニュートン法による近似計算
1913: for ($i = 1; $i < 23; $i++) {
1914: list($year, $month, $day, $hour, $min, $sec) = $this->JD2Gregorian($jdc, $tdiff);
1915: $ym = $this->longitude_moon($year, $month, $day, $hour, $min, $sec, $tdiff);
1916: $ys = $this->longitude_sun($year, $month, $day, $hour, $min, $sec, $tdiff);
1917:
1918: // 太陽と月の黄緯差180度を目指す.
1919: $dy = $ym - $ys - 180.0;
1920:
1921: // 引き込み範囲に入ったら補正する.
1922: if ($dy <= -360.0) {
1923: $dy += 360.0;
1924: } else if ($dy >= 0.0) {
1925: $dy -= 360.0;
1926: }
1927:
1928: // 誤差内に入ったらループを脱出する.
1929: if ($dy >= 0.0 && $dy <= 0.0001) break;
1930: if ($dy < -0.0 && $dy >= -0.0001) break;
1931:
1932: $dd = $dy / $dif;
1933: $jdc -= $dd;
1934: }
1935:
1936: return array($year, $month, $day, $hour, $min, $sec);
1937: }
太陽の視黄経の計算メソッド longitude_sun と月の視黄経の計算メソッド longitude_moon はすでに説明したとおりだが、黄経値から年月日を計算する逆関数は存在しないため、近似計算によって求めている。このため、国立天文台が発表する時刻と数分のズレがある。
解説:月の視半径を求める
pahooCalendar.php
1711: /**
1712: * J2000.0からの経過年数における月の視差(度)を求める。
1713: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-44-01.shtm
1714: * @param float $jy 2000.0からの経過年数
1715: * @return float 月の視差(度)
1716: */
1717: function __dif_moon($jy) {
1718: $p_moon = 0.0003 * sin(deg2rad($this->__angle(227.0 + 4412.0 * $jy)));
1719: $p_moon += 0.0004 * sin(deg2rad($this->__angle(194.0 + 3773.4 * $jy)));
1720: $p_moon += 0.0005 * sin(deg2rad($this->__angle(329.0 + 8545.4 * $jy)));
1721: $p_moon += 0.0009 * sin(deg2rad($this->__angle(100.0 + 13677.3 * $jy)));
1722: $p_moon += 0.0028 * sin(deg2rad($this->__angle( 0.0 + 9543.98 * $jy)));
1723: $p_moon += 0.0078 * sin(deg2rad($this->__angle(325.7 + 8905.34 * $jy)));
1724: $p_moon += 0.0095 * sin(deg2rad($this->__angle(190.7 + 4133.35 * $jy)));
1725: $p_moon += 0.0518 * sin(deg2rad($this->__angle(224.98 + 4771.989 * $jy)));
1726: $p_moon += 0.9507 * sin(deg2rad($this->__angle(90.0)));
1727:
1728: return $p_moon;
1729: }
pahooCalendar.php
1731: /**
1732: * 指定した日時における月の視差(度)を求める(日時はローカル時間)。
1733: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-44-01.shtm
1734: * @param int $year, $month, $day グレゴリオ暦による年月日
1735: * @param float $hour, $min, $sec 時分秒(ローカル時間)
1736: * @param float $tdiff UTCとの時差;NULLの時はTDIFF
1737: * @return float 月の視差
1738: */
1739: function dif_moon($year, $month, $day, $hour, $min, $sec, $tdiff=NULL) {
1740: $jy = $this->Gregorian2JY($year, $month, $day, $hour, $min, $sec, $tdiff);
1741:
1742: return $this->__dif_moon($jy);
1743: }
pahooCalendar.php
1745: /**
1746: * 指定した日時における月の視半径(度)を求める(日時はローカル時間)。
1747: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-50-01.shtm
1748: * @param int $year, $month, $day グレゴリオ暦による年月日
1749: * @param float $hour, $min, $sec 時分秒(ローカル時間)
1750: * @param float $tdiff UTCとの時差;NULLの時はTDIFF
1751: * @return float 月の視半径(度)
1752: */
1753: function rad_moon($year, $month, $day, $hour, $min, $sec, $tdiff=NULL) {
1754: $dif = $this->dif_moon($year, $month, $day, $hour, $min, $sec, $tdiff);
1755: $rad = asin(0.2725 * sin(deg2rad($dif)));
1756:
1757: return rad2deg($rad);
1758: }
これを rad_moon として実装している。
$$ rad = sin^{-1}(0.2725 \times sin(dif)) $$
解説:ある期間に起きる満月と視半径を計算
supermoon.php
204: /**
205: * ある期間に起きる満月と視半径を計算
206: * @param int $year 開始年(西暦)
207: * @param int $month 開始月
208: * @param int $term 計算期間(月)
209: * @param array $items 計算結果を格納する配列
210: * @return int 満月の回数
211: */
212: function calcSuperMoon($year, $month, $term, &$items) {
213: // 暦計算に関わるクラス
214: $pcl = new pahooCalendar(LANGUAGE, UTCDIFF);
215:
216: $i = $cnt = 0;
217: $day = 1;
218: while ($i < $term) {
219: // 次の満月の日時を求める
220: list($year1, $month1, $day1, $hour1, $min1, $sec1) = $pcl->next_fullmoon($year, $month, $day, 0, 0, 0);
221: $items[$cnt]['year'] = $year1;
222: $items[$cnt]['month'] = $month1;
223: $items[$cnt]['day'] = $day1;
224: $items[$cnt]['week'] = $pcl->getWeekString($year1, $month1, $day1);
225: $items[$cnt]['hour'] = $hour1;
226: $items[$cnt]['min'] = $min1 + round($sec1 / 60.0, 0);
227: // 月の視半径
228: $items[$cnt]['rad'] = $pcl->rad_moon($year1, $month1, $day1, $hour1, $min1, $sec1);
229: // 満月の呼び名
230: $items[$cnt]['name'] = $pcl->getFullMoonNickname($month1);
231: // 次のパラメータを用意する
232: $cnt++;
233: $year = $year1;
234: if ($month < $month1) $i++;
235: $month = $month1;
236: $day = $day1 + 20.0; // 次の計算基準は26日後
237: if ($day > $pcl->getDaysInMonth($year, $month)) {
238: $day = 1;
239: $month++;
240: $i++;
241: if ($month > 12) {
242: $month = 1;
243: $year++;
244: }
245: }
246: }
247: // オブジェクト解放
248: $pcl = NULL;
249:
250: return $cnt;
251: }
解説:満月の呼び名
pahooCalendar.php
1979: /**
1980: * 指定した月の満月の呼び名を求める.
1981: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-50-01.shtm
1982: * @param int $month 月
1983: * @return string 満月の呼び名
1984: */
1985: function getFullMoonNickname($month) {
1986: $table_jp = array(
1987: 'ウルフムーン',
1988: 'スノームーン',
1989: 'ワームムーン',
1990: 'ピンクムーン',
1991: 'フラワームーン',
1992: 'ストロベリームーン',
1993: 'バックムーン', // または「バクムーン」.発音はbʌkだが,buckskinをバックスキンと読むことから,ここでは「バクムーン」にした.
1994: 'スタージョンムーン', // または「スタージャンムーン」.Twitterでアンケートをとて「スタージョンムーン」にした. https://twitter.com/papa_pahoo/status/1620259072871395328
1995: 'ハーベストムーン',
1996: 'ハンターズムーン',
1997: 'ビーバームーン',
1998: 'コールドムーン'
1999: );
2000:
2001: $table_en = array(
2002: 'Wolf Moon',
2003: 'Snow Moon',
2004: 'Worm Moon',
2005: 'Pink Moon',
2006: 'Flower Moon',
2007: 'Strawberry Moon',
2008: 'Buck Moon',
2009: 'Sturgeon Moon',
2010: 'Harvest Moon',
2011: 'Hunter\#x27;s Moon',
2012: 'Beaver Moon',
2013: 'Cold Moon'
2014: );
2015:
2016: $month = (int)$month;
2017: if (($month >= 1) && ($month << 12)) {
2018: if ($this->language == 'jp') {
2019: $name = $table_jp[$month - 1];
2020: } else {
2021: $name = $table_en[$month - 1];
2022: }
2023: } else {
2024: $name = '';
2025: }
2026:
2027: return $name;
2028: }
7月の Buck Moon の buk(雄ジカ)は発音はbʌkだが、buckskinをバックスキンと読むことから、ここでは「バクムーン」にした。
8月の Sturgeon Moon の sturgeon(チョウザメ)の発音はstɚːdʒənだが、Wikipedia日本語版にある Sturgeon をもつ人名の表記は揺れている。
- ウィリアム・スタージャン - イギリスの物理学者。
- シオドア・スタージョン - アメリカのSF作家。
- ニコラ・スタージョン - スコットランドの政治家。
- ローリン・S・スタージョン - アメリカの映画監督
8月の満月「スタージャンムーン」のカタカナ表記を見直そうかどうか迷っています。
— パパぱふぅ@𝙥𝙖𝙝𝙤𝙤.𝙤𝙧𝙜 (@papa_pahoo) 2023年1月31日
英語表記 Sturgeon Moon
Sturgeonは「チョウザメ」。
よろしければアンケートにご回答ください。
解説:一覧表作成
supermoon.php
254: /**
255: * 満月一覧から表示用HTMLを求める.
256: * @param array $items 計算結果
257: * @return string HTML文字列
258: */
259: function makeTable($items) {
260: // 最大・最小の視半径を求める
261: $minrad = 999;
262: $minid = -1;
263: $maxrad = 0;
264: $maxid = -1;
265: foreach ($items as $key=>$item) {
266: if ($item['rad'] < $minrad) {
267: $minrad = $item['rad'];
268: $minid = $key;
269: }
270: if ($item['rad'] > $maxrad) {
271: $maxrad = $item['rad'];
272: $maxid = $key;
273: }
274: }
275:
276: // 一覧表作成
277: $width = WIDTH;
278: $outstr =<<< EOT
279: <table style="width:{$width};">
280: <tr><th>年月日・時</th><th colspan="2">月の視半径<br /><span class="comp">(最小半径を100%)</span></th><th>明るさの比<br /><span class="comp">(最小半径を100%)</span></th><th>呼び名</th></tr>
281:
282: EOT;
283: foreach ($items as $key=>$item) {
284: $ymd = sprintf("%04d年%02d月%02d日(%s) %02d:%02d",
285: $item['year'], $item['month'], $item['day'], $item['week'], $item['hour'], $item['min']);
286: $mm = intval($item['rad'] * 60);
287: $s1 = intval(($item['rad'] * 60 - $mm) * 60);
288: $s2 = ($item['rad'] * 60 - $mm - $s1 / 60) * 60 * 100;
289: $rad = sprintf("%2d'%02d\".%02d", $mm, $s1, $s2);
290: $rat = sprintf("%3.1f", $item['rad'] / $minrad * 100);
291: $brg = sprintf("%3.1f", pow($item['rad'] / $minrad, 2) * 100);
292:
293: // 背景色
294: if ($key == $minid) {
295: $color = ' style="background-color:#' . MIN_COLOR . ';"';
296: } else if ($key == $maxid) {
297: $color = ' style="background-color:#' . MAX_COLOR . ';"';
298: } else {
299: $color = '';
300: }
301:
302: $outstr .=<<< EOT
303: <tr{$color}>
304: <td>{$ymd}</td>
305: <td>{$rad}</td>
306: <td>{$rat}%</td>
307: <td>{$brg}%</td>
308: <td>{$item['name']}</td>
309: </tr>
310:
311: EOT;
312: }
313: $outstr .=<<< EOT
314: </table>
315: </body>
316:
317: EOT;
318:
319: return $outstr;
320: }
冒頭で、期間中の最小半径を求める。
これを基準に、視半径の比率、明るさの比率(半径の2乗)を計算し、一覧表にしてゆく。
活用例
参考サイト
- PHPで月齢を計算:ぱふぅ家のホームページ
- PHPで二十四節気・七十二候一覧を作成:ぱふぅ家のホームページ
- スーパームーン;AstroArts
- 「スーパームーン」ってなに?:国立天文台
- 暦Wiki/月の満ち欠け/月齢と満ち欠け]:国立天文台暦計算室
- 明日はスーパームーン:鹿角平天文台通信
- スーパームーンを調べる:みんなの知識 ちょっと便利帳

「PHPで月齢を計算」で月齢を求めるプログラムを作ったが、今回は満月の時の月の大きさ(視半径)を計算するプログラムを作ってみることにする。
(2025年11月23日)pahooCalendar.next_fullmoonmメソッドの不具合修正