PHPで日出没・月出没・月齢・潮を計算

(1/1)
PHP で二十四節気一覧を作成」「PHP で月齢を計算」では、太陽や月の位置を計算する方法を紹介した。今回は、これらを利用し、日の出・日の入り・月の出・月の入りの時刻、月齢、潮の大小を計算する PHP プログラムをつくってみる。

(2021 年 5 月 8 日)PHP8 対応,リファラ・チェック改良

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

PHPで日出没・月出没・月齢を計算

目次

サンプル・プログラム

各種暦計算、太陽や月の位置計算は、クラス pahooCalendar として分離している。
圧縮ファイルの内容
myCalendar.phpサンプル・プログラム本体。
pahooCalendar.php暦計算クラス pahooCalendar、潮位計算クラス pahooTide。
include_pathが通ったディレクトリに配置すること。

解説:月出・月没時刻の計算

1024: /**
1025:  * 月の出/月の入り/南中
1026:  * @param int $mode 0=出, 1=没, 2=南中
1027:  * @param int $year, $month, $day  グレゴリオ暦による年月日
1028:  * @param double $longitude 観測値の経度(東経は正数)
1029:  * @param double $latitude  観測値の緯度
1030:  * @param double $height 観測値の高さ
1031:  * @return double 時刻(単位:日)/FALSE 月出/月没がない
1032: */
1033: function moon_time($mode$longitude$latitude$height$year$month$day) {
1034:     //地球自転遅れ補正値(日)計算
1035:     $rotate_rev = (57.0 + 0.8 * ($year - 1990)) / 86400.0;
1036: 
1037:     //2000年1月1日力学時正午からの経過日数(日)計算
1038:     $day_progress = $this->J2000($year$month$day);
1039: 
1040:     //逐次計算時刻(日)初期設定
1041:     $time_loop = 0.5;
1042: 
1043:     //補正値初期値
1044:     $rev = 1.0;
1045: 
1046:     //地平線伏角
1047:     $dip = 0.0353333 * sqrt($height);
1048: 
1049:     $diff_moon = 0;
1050:     $height_moon = 0;
1051:     while (abs($rev) > $this->CONVERGE) {
1052:         //経過ユリウス年(日)計算
1053:         //( 2000.0(2000年1月1日力学時正午)からの経過年数 (年) )
1054:         $jy = ($day_progress + $time_loop + $rotate_rev) / 365.25;
1055:         //月の黄経
1056:         $long_moon = $this->__longitude_moon($jy);
1057:         //月の黄緯
1058:         $lat_moon = $this->__latitude_moon($jy);
1059:         //黄道 → 赤道変換
1060:         list($alpha$delta) = $this->__eclip2equat($long_moon$lat_moon$jy);
1061:         if ($mode != 2) {
1062:             //月の視差
1063:             $dif_moon = $this->__dif_moon($jy);
1064:             //月の出没高度
1065:             $height_moon = -1 * $this->ASTRO_REFRACT - $dip + $dif_moon;
1066:         }
1067:         //恒星時
1068:         $sidereal = $this->__sidereal($jy$time_loop$longitude);
1069:         //時角差計算
1070:         $hour_ang_dif = $this->hour_ang_dif($mode$alpha$delta$latitude$height_moon$sidereal);
1071: 
1072:         //仮定時刻に対する補正値
1073:         $rev = $hour_ang_dif / 347.8;
1074:         $time_loop += $rev;
1075:     }
1076: 
1077:     //月出/月没がない場合は 0 とする
1078:     return ($time_loop < 0 || $time_loop >=1) ? FALSE : $time_loop;
1079: }

計算式は『日の出・日の入りの計算』(長沢工=著)による。

月の出、月の入り、月の南中(真南に来ること)の時刻はユーザー関数 moon_time で計算する。
計算の基準となる日時は、2000 年(平成 12 年)1 月 1 日力学時正午からの経過年数 $jy とする。
まず、月の位置(視黄経,視黄緯)を計算する。黄経,黄緯は、黄道(太陽の通り道)を基準とした直交座標系である。
次に、黄経,黄緯を赤経,赤緯に変換する。赤経,赤緯は、地球の経度・緯度を空に延長した直交座標系である。
ここまでで計算した座標は、月の中心の位置をあらわす。月の出、月の入りについては、月の中心座標が地平線を通過したときと定義されているので、これをそのまま時刻計算に持ち込めばよい。ただし、視差を考慮する必要がある。
なお、日の出は太陽の上縁が地平線に接した時刻、日の入りは太陽の下縁が地平線に接した時刻と定義されている。

解説:潮の計算

1152: /**
1153:  * 潮を求める
1154:  * @param int $year, $month, $day  グレゴリオ暦による年月日
1155:  * @param double $hour, $min, $sec 時分秒(世界時)
1156:  * @return string 潮
1157: */
1158: function tide($year$month$day$hour$min$sec) {
1159:     //黄経差=>潮(気象庁方式)
1160:     static $table = array(
1161:  36 => '大潮',
1162:  72 => '中潮',
1163: 108 => '小潮',
1164: 120 => '長潮',
1165: 132 => '若潮',
1166: 168 => '中潮',
1167: 216 => '大潮',
1168: 252 => '中潮',
1169: 288 => '小潮',
1170: 300 => '長潮',
1171: 312 => '若潮',
1172: 348 => '中潮',
1173: 360 => '大潮'
1174: );
1175: 
1176:     $longitude_sun  = $this->longitude_sun($year$month$day$hour$min$sec);
1177:     $longitude_moon = $this->longitude_moon($year$month$day$hour$min$sec);
1178:     //Δλ=λmoon-λsun
1179:     $delta_rm = $this->__angle($longitude_moon - $longitude_sun);
1180: 
1181:     foreach ($table as $key=>$val) {
1182:         if ($delta_rm < $key) {
1183:             $tide = $val;
1184:             break;
1185:         }
1186:     }
1187: 
1188:     return $tide;
1189: }

月と太陽の位置関係によって潮汐が起きる。

潮の大小は、月と太陽の位相(黄経差)でほぼ決まる。
ユーザー関数 longitude_sunlongitude_moon の差をとって、潮の大小を取得する関数が tide である。
黄経差は気象庁方式を採った。つまり、下記のようになる。
黄経差 潮の大小
348~36度 大潮
36~72度 中潮
72~108度 小潮
108~120度 長潮
120~132度 若潮
132~168度 中潮
168~216度 小潮
216~252度 中潮
252~288度 小潮
288~300度 長潮
300~316度 若潮
312~348度 中潮

質疑応答

【質問】 ニックリネーム様

はじめまして。
・月齢・月出・月没・月南中
を Android スマホのウィジェットで表示するアプリを作成中で、ぱふぅ家様のページにある PHP ソースコードを流用して実装したいと思っています(Java に変換)。
広告付きアプリにはウンザリしており、無料・広告無しで公開しアプリの説明で参考情報としてぱふぅ家様の該当ページへのリンクを記載いたします。
二次利用に関する説明ページは確認済みですが、もし何か問題がございましたらご指摘いただけますでしょうか。


【回答】

リンクを記載していただけるとのこと、ありがとうございます。
どうぞご活用ください。


【質問】 ニックリネーム様

ありがとうございます。Java で実装はほぼ終わったのですが
var $TDIFF = 9.0;
を例えば $TDIFF=8.0; にしても月出/月没の時間が1時間ではなく数分しかずれません。
TDIFF=9 なら月出/月没/南中の出力結果はぱふぅ様のページと同じになるのでコードの移植はできていると思うのですが PHP環境で試せていません。誠に勝手なお願いで恐縮ですが PHP環境でも同様か、ご確認いただけませんでしょうか。


【回答】

$TDIFF は、日本標準時をベースに用意された近似式に対応するための補正値です。他国の標準時に変換することはできません。9.0 固定にしてください。

参考書籍

表紙 日の出・日の入りの計算
著者 長沢工
出版社 地人書館
サイズ 単行本
発売日 1999年12月
価格 1,650円(税込)
rakuten
ISBN 9784805206348
 

参考サイト

(この項おわり)
header