PHPで土用を求める

(1/1)
炭や一風の天然うなぎ蒲焼
炭や一風の天然うなぎ蒲焼
土用の丑の日といえばウナギである。土用の期間は太陽黄経から、丑の日は日の干支から求めることができる。
今回は、PHPを使って指定した年の土用と丑の日を一覧表示するプログラムを作ってみよう。
(2023年1月15日)二の丑に対応,数値入力にpahooInputData導入

目次

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

PHPで土用を求める

サンプル・プログラム

圧縮ファイルの内容
getDoyo.phpサンプル・プログラム本体。
pahooCalendar.php暦・潮位計算クラス pahooCalendar。
暦・潮位計算クラスの使い方は「PHPで二十四節気・七十二候一覧を作成」「PHPで月齢を計算」「PHPで日出没・月出没・月齢・潮を計算」「PHPで潮位を計算する」などを参照。include_path が通ったディレクトリに配置すること。
pahooInputData.phpデータ入力に関わる関数群。
使い方は「PHPでGET/POSTでフォームから値を受け取る」「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。
getDoyo.php 更新履歴
バージョン 更新日 内容
1.1.0 2023/01/15 二の丑に対応,数値入力にpahooInputData導入
1.0 2021/08/01 初版
pahooCalendar.php 更新履歴
バージョン 更新日 内容
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 表記改訂:バクムーン→バックムーン,スタージャンムーン→スタージョンムーン,七十二候
pahooInputData.php 更新履歴
バージョン 更新日 内容
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() 追加

土用の丑の日とは

土用の丑の日といえば、うなぎを食べる風習がある。江戸時代、平賀源内が宣伝したことでこの風習が広まったとされるが、そもそも土用の丑の日とは、どうやって決めるのだろうか。
四季と土用
むかし、中国で陰陽五行説の5つの要素(木・火・土・金・水)を四季(春・夏・秋・冬)に対応させようとした。そこで、春・夏・秋・冬の各々に木・火・土・金を1対1対応させ、各季節の最後の約18日に残ったを割り当てた。この約18日間を土用と呼ぶ。
左図のように、立春の前日までが冬の土用、立夏の前日までが春の土用、立秋の前日までが夏の土用、立冬の前日までが秋の土用となる。
土用の入りと明けは太陽黄経で定義できる。
季節 太陽黄経
土用の入り 土用の明け
297度 315度(立春)の前日
27度 45度(立夏)の前日
117度 135度(立秋)の前日
207度 225度(立冬)の前日
土用の丑の日は、土用の期間中の丑の日のことである。とくに夏の土用に対して用いられる。
日の干支は、「干支と十二支の計算 - PHPで3ヶ月カレンダーを作る」をご覧頂きたい。日の干支は12日で1周するので、土曜の期間中に丑の日が2回来るケースがある。2回目の丑の日を二の丑と呼ぶことがある。

準備:初期値など

  36: //指定できる西暦年の範囲
  37: define('MIN_YEAR', 1901);
  38: define('MAX_YEAR', 2099);
  39: 
  40: //表示言語(jp:日本語, en:英語, en3:英語略記)
  41: define('LANGUAGE', 'jp');
  42: 
  43: //世界時からの時差(日本標準時)
  44: define('UTCDIFF', +9.0);
  45: 
  46: //西暦年の選択範囲(年)
  47: define('INTERVAL', 5);
  48: 
  49: //丑の日の背景色
  50: define('COLOR_USHI', 'gold');
  51: 
  52: //表示幅(ピクセル)
  53: define('WIDTH', 600);
  54: 
  55: //require_once()で呼ぶファイルはinclude_pathが通っているフォルダに配置すること。
  56: //暦計算クラス
  57: require_once('pahooCalendar.php');
  58: 
  59: //データ入力に関わる関数群
  60: require_once('pahooInputData.php');

あらかじめ、計算期間(月)と世界時からの時差を定数として定義しておく。

土用の日を求めるには、ユーザークラス "pahooCalendar" に用意したメソッド群を利用する。
オブジェクト生成時に、表示言語として "ja"(日本語)を、世界時との時差としてユーザー定義の定数 UTCDIFF を渡しておく。こうすることで、pahooCalendar クラスが出力する文字列は日本語に、日時計算は時差 UTCDIFF がある前提で計算を行う。

入力した数値の取得とバリデーションチェックに、ユーザー定義クラス群 "pahooInputData.php" を利用している。

解説:土用を求める

1204: /**
1205:  * 指定した年の土用を求める.
1206:  * 参考サイト https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_isDoyo
1207:  * @param   int $year 西暦年
1208:  * @return  array   [0]['in']['year','month','day']     冬の土用の入り
1209:  *                     ['ushi']['year','month','day']   冬の土用の丑の日
1210:  *                     ['out']['year','month','day']    冬の土用の明け
1211:  *                  [1]                                 春の土用の入り/明け
1212:  *                  [2]                                 夏の土用の入り/明け
1213:  *                  [3]                                 秋の土用の入り/明け
1214: */
1215: function getDoyo($year) {
1216:     static $table1 = array(297, 360, 27, 117, 207, 297);
1217:     static $table2 = array(315, 360, 45, 135, 225, 315);
1218:     $key  = 0;
1219:     $flag = 0;          //土用期間中フラグ
1220:     $doyo = array();    //土用の入り/明けを格納
1221: 
1222:     for ($month = 1$month <12$month++) {
1223:         $day_in_month = $this->getDaysInMonth($year, $month);
1224:         for ($day = 1$day <$day_in_month$day++) {
1225:             //太陽黄経
1226:             $l1 = $this->longitude_sun($year, $month, $day, 24, 0, 0);
1227:             $l2 = $this->longitude_sun($year, $month, $day, 48, 0, 0);
1228:             //入り判定
1229:             if (($flag == 0&& ($l1 > $table1[$key]) && ($l1 <$table1[$key + 1])) {
1230:                 $key2 = ($key > 0? $key - 1 : $key;
1231:                 $doyo[$key2]['in']['year']  = $year;
1232:                 $doyo[$key2]['in']['month'] = $month;
1233:                 $doyo[$key2]['in']['day']   = $day;
1234:                 $flag = 1;
1235:             }
1236:             if ($flag > 0) {
1237:                 //明け判定
1238:                 if (($l2 >$table2[$key]) && ($l2 <$table2[$key + 1])) {
1239:                     $key2 = ($key > 0? $key - 1 : $key;
1240:                     $doyo[$key2]['out']['year']  = $year;
1241:                     $doyo[$key2]['out']['month'] = $month;
1242:                     $doyo[$key2]['out']['day']   = $day;
1243:                     $key++;
1244:                     $flag = 0;
1245:                     if ($key == 1)  $key++;
1246:                     if ($key > 4)   return $doyo;
1247:                 //丑の日判定
1248:                 } else if (($flag == 1&& (preg_match('/丑/ui', $this->eto_day($year, $month, $day)) > 0)) {
1249:                     $key2 = ($key > 0? $key - 1 : $key;
1250:                     $doyo[$key2]['ushi']['year']  = $year;
1251:                     $doyo[$key2]['ushi']['month'] = $month;
1252:                     $doyo[$key2]['ushi']['day']   = $day;
1253:                     $flag++;
1254:                     if ($key > 4)   return $doyo;
1255:                 //二の丑の日判定
1256:                 } else if (($flag == 2&& (preg_match('/丑/ui', $this->eto_day($year, $month, $day)) > 0)) {
1257:                     $key2 = ($key > 0? $key - 1 : $key;
1258:                     $doyo[$key2]['ushi2']['year']  = $year;
1259:                     $doyo[$key2]['ushi2']['month'] = $month;
1260:                     $doyo[$key2]['ushi2']['day']   = $day;
1261:                     $flag++;
1262:                 }
1263:             }
1264:         }
1265:     }
1266:     return $doyo;
1267: }

土用は、メソッド getDoyo で求める。
指定した年の1月1日から毎日の太陽黄経を計算し、翌日(24時間後)が297度、27度、117度、207度を超えたら、土用の入りとして年月日を配列 $doyo に代入し、$flag に1を代入する。
日の干支を求め、最初にの文字が入っていた日を土用の丑の日として年月日を配列 $doyo に代入し、$flag に2を代入する。
次にの文字が見つかったら、二の丑として年月日を配列 $doyo に代入し、$flag に3を代入する。
太陽黄経が、翌々日(48時間後)が315度(立春)、45度(立夏)、135度(立秋)、225度(立冬)を超えたら、土用の明けとして年月日を配列 $doyo に代入し、$flag を0に戻す。
太陽黄経は、途中で360度を超えて0度に戻るところを配列 $table1, $table2 について工夫している。

参考サイト

(この項おわり)
header