サンプル・プログラムの実行例
サンプル・プログラム
myCalendar.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 | 計算精度向上 |
1.3 | 2021/05/08 | PHP8対応,リファラ・チェック改良 |
1.2 | 2020/01/02 | リファラチェック追加 |
1.11 | 2018/01/03 | 月齢は日本時21時に変更 |
バージョン | 更新日 | 内容 |
---|---|---|
4.3.2 | 2023/02/11 | getSolarTerm72() 表記改訂:水澤腹堅→水沢腹堅 |
4.3.1 | 2023/02/03 | 表記改訂:バクムーン→バックムーン,スタージャンムーン→スタージョンムーン,七十二候 |
4.3.0 | 2023/01/14 | コメント表記などを見直した,tenshanichi()追加 |
4.2.0 | 2023/01/11 | getTimeDifference(),setTimeDifference()追加 |
4.1.0 | 2023/01/09 | 太陽,月の位置計算の基準をUTCに変更した |
バージョン | 更新日 | 内容 |
---|---|---|
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() 追加 |
解説:日出・日没時刻の計算
699: /**
700: * 指定した年月日の日出/日没/南中の時刻を求める(日時はローカル時間).
701: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-44-01.shtm
702: * @param int $mode 0=出, 1=没, 2=南中
703: * @param int $year, $month, $day 年月日
704: * @param float $longitude 観測値の経度(東経は正数)
705: * @param float $latitude 観測値の緯度
706: * @param float $height 観測値の高さ
707: * @param float $tdiff UTCとの時差;NULLの時はTDIFF(省略時NULL)
708: * @return float 時(分秒以下は小数)
709: */
710: function sun_time($mode, $longitude, $latitude, $height, $year, $month, $day, $tdiff=NULL) {
711: //地球自転遅れ補正値(日)計算
712: $rotate_rev = (57.0 + 0.8 * ($year - 1990)) / 86400.0;
713:
714: //2000年1月1日力学時正午からの経過日数(日)計算
715: $day_progress = $this->J2000($year, $month, $day, 0, 0, 0, $tdiff);
716:
717: //逐次計算時刻(日)初期設定
718: $time_loop = 0.5;
719:
720: //補正値初期値
721: $rev = 1.0;
722:
723: //地平線伏角
724: $dip = 0.0353333 * sqrt($height);
725:
726: while (abs($rev) > $this->CONVERGE) {
727: //経過ユリウス年(日)計算
728: //( 2000.0(2000年1月1日力学時正午)からの経過年数 (年) )
729: $jy = ($day_progress + $time_loop + $rotate_rev) / 365.25;
730: //太陽の黄経
731: $long_sun = $this->__longitude_sun($jy);
732: //太陽の距離
733: $dist_sun = $this->__distance_sun($jy);
734: //黄道 → 赤道変換
735: list($alpha, $delta) = $this->__eclip2equat($long_sun, 0, $jy);
736: //太陽の視半径
737: $r_sun = 0.266994 / $dist_sun;
738: //太陽の視差
739: $dif_sun = 0.0024428 / $dist_sun;
740: //太陽の出入高度
741: $height_sun = -1.0 * $r_sun - $this->ASTRO_REFRACT - $dip + $dif_sun;
742: //恒星時
743: $sidereal = $this->__sidereal($jy, $time_loop, $longitude);
744: //時角差計算
745: $hour_ang_dif = $this->hour_ang_dif($mode, $alpha, $delta, $latitude, $height_sun, $sidereal);
746:
747: //仮定時刻に対する補正値
748: $rev = $hour_ang_dif / 360.0;
749: $time_loop += $rev;
750: }
751:
752: return $time_loop;
753: }
計算の基準となる日時は、2000年(平成12年)1月1日力学時正午からの経過年数 $jy とする。
まず、太陽の位置(視黄経、視黄緯)を計算する。黄経、黄緯(黄道座標系)については、「解説:視黄経の算出 - PHPで二十四節気・七十二候一覧を作成」で説明したとおりだ。
後述する月出・月没・月南中時刻の計算とともに、計算式は『日の出・日の入りの計算』(長沢工=著)を参考にした。
538: /**
539: * 黄道座標から赤道座標を求める(J2000.0分点).
540: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-44-01.shtm
541: * @param float $ramda, $beta 黄経,黄緯
542: * @param float $jy J2000.0からの経過年数
543: * @return float (赤経,赤緯)
544: */
545: function __eclip2equat($rambda, $beta, $jy) {
546: $e = (float)deg2rad(23.439291 - 0.000130042 * $jy); //黄道傾角
547: $rambda = (float)deg2rad($rambda);
548: $beta = (float)deg2rad($beta);
549:
550: $a = (float)cos($beta) * cos($rambda);
551: $b = (float)-1.0 * sin($beta) * sin($e);
552: $b += (float)cos($beta) * sin($rambda) * cos($e);
553: $c = (float)sin($beta) * cos($e);
554: $c += (float)cos($beta) * sin($rambda) * sin($e);
555:
556: $alpha = (float)$b / $a;
557: $alpha = (float)rad2deg(atan($alpha));
558: if ($a < 0.0) (float)$alpha += 180.0;
559: if ($alpha < 0.0) (float)$alpha += 360.0;
560:
561: $delta = (float)rad2deg(asin($c));
562:
563: return array($alpha, $delta);
564: }
566: /**
567: * 黄道座標から赤道座標を求める(指定したローカル時間分点).
568: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-44-01.shtm
569: * @param float $ramda, $beta 黄経,黄緯
570: * @param float $hour, $min, $sec 時分秒(ローカル時間)
571: * @param float $tdiff UTCとの時差;NULLの時はTDIFF(省略時NULL)
572: * @return float (赤経,赤緯)
573: */
574: function eclip2equat($rambda, $beta, $year, $month, $day, $hour, $min, $sec, $tdiff=NULL) {
575: $jy = $this->Gregorian2JY($year, $month, $day, $hour, $min, $sec, $tdiff);
576:
577: return $this->__eclip2equat($rambda, $beta, $jy);
578: }
解説:月出・月没・月南中時刻の計算
1669: /**
1670: * 指定した年月日における月の出/月の入り/南中の時刻を求める.
1671: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-44-01.shtm
1672: * @param int $mode 0=出, 1=没, 2=南中
1673: * @param int $year, $month, $day グレゴリオ暦による年月日
1674: * @param float $longitude 観測値の経度(東経は正数)
1675: * @param float $latitude 観測値の緯度
1676: * @param float $height 観測値の高さ
1677: * @param float $tdiff UTCとの時差;NULLの時はTDIFF(省略時NULL)
1678: * @return float 時刻(単位:日)/FALSE 月出/月没がない
1679: */
1680: function moon_time($mode, $longitude, $latitude, $height, $year, $month, $day) {
1681: //地球自転遅れ補正値(日)計算
1682: $rotate_rev = (57.0 + 0.8 * ($year - 1990.0)) / 86400.0;
1683:
1684: //2000年1月1日力学時正午からの経過日数(日)計算
1685: $day_progress = $this->J2000($year, $month, $day, 0, 0, 0);
1686:
1687: //逐次計算時刻(日)初期設定
1688: $time_loop = 0.5;
1689:
1690: //補正値初期値
1691: $rev = 1.0;
1692:
1693: //地平線伏角
1694: $dip = 0.0353333 * sqrt($height);
1695:
1696: $diff_moon = 0.0;
1697: $height_moon = 0.0;
1698: while (abs($rev) > $this->CONVERGE) {
1699: //経過ユリウス年(日)計算
1700: //( 2000.0(2000年1月1日力学時正午)からの経過年数 (年) )
1701: $jy = ($day_progress + $time_loop + $rotate_rev) / 365.25;
1702: //月の黄経
1703: $long_moon = $this->__longitude_moon($jy);
1704: //月の黄緯
1705: $lat_moon = $this->__latitude_moon($jy);
1706: //黄道 → 赤道変換
1707: list($alpha, $delta) = $this->__eclip2equat($long_moon, $lat_moon, $jy);
1708: if ($mode != 2) {
1709: //月の視差
1710: $dif_moon = $this->__dif_moon($jy);
1711: //月の出没高度
1712: $height_moon = -1.0 * $this->ASTRO_REFRACT - $dip + $dif_moon;
1713: }
1714: //恒星時
1715: $sidereal = $this->__sidereal($jy, $time_loop, $longitude);
1716: //時角差計算
1717: $hour_ang_dif = $this->hour_ang_dif($mode, $alpha, $delta, $latitude, $height_moon, $sidereal);
1718:
1719: //仮定時刻に対する補正値
1720: $rev = $hour_ang_dif / 347.8;
1721: $time_loop += $rev;
1722: }
1723:
1724: //月出/月没がない場合は FALSE とする
1725: return ($time_loop < 0.0 || $time_loop >= 1.0) ? FALSE : $time_loop;
1726: }
なお、日の出は太陽の上縁が地平線に接した時刻、日の入りは太陽の下縁が地平線に接した時刻と定義されている。
解説:潮の計算
1848: /**
1849: * 指定した日時の潮を求める(日時はローカル時間).
1850: * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-44-01.shtm#php_tide
1851: * @param int $year, $month, $day グレゴリオ暦による年月日
1852: * @param float $tdiff UTCとの時差;NULLの時はTDIFF(省略時NULL)
1853: * @return string 潮
1854: */
1855: function tide($year, $month, $day, $hour, $min, $sec, $tdiff=NULL) {
1856: //黄経差=>潮(気象庁方式)
1857: static $table = array(
1858: 36 => '大潮',
1859: 72 => '中潮',
1860: 108 => '小潮',
1861: 120 => '長潮',
1862: 132 => '若潮',
1863: 168 => '中潮',
1864: 216 => '大潮',
1865: 252 => '中潮',
1866: 288 => '小潮',
1867: 300 => '長潮',
1868: 312 => '若潮',
1869: 348 => '中潮',
1870: 360 => '大潮'
1871: );
1872:
1873: $longitude_sun = $this->longitude_sun($year, $month, $day, $hour, $min, $sec, $tdiff);
1874: $longitude_moon = $this->longitude_moon($year, $month, $day, $hour, $min, $sec, $tdiff);
1875: //Δλ=λmoon-λsun
1876: $delta_rm = $this->__angle($longitude_moon - $longitude_sun);
1877:
1878: foreach ($table as $key=>$val) {
1879: if ($delta_rm < $key) {
1880: $tide = $val;
1881: break;
1882: }
1883: }
1884:
1885: return $tide;
1886: }
潮の大小は、月と太陽の位相(黄経差)でほぼ決まる。
ユーザー関数 longitude_sun と longitude_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固定にしてください。
参考サイト
- PHPで二十四節気一覧を作成:ぱふぅ家のホームページ
- PHPで月齢を計算:ぱふぅ家のホームページ
(2023年1月14日)計算精度を向上した。数値入力にSpinner、pahooInputDataを導入した。