oops-Lunar
[ class tree: oops-Lunar ] [ index: oops-Lunar ] [ all elements ]

Source for file Lunar.php

Documentation is available at Lunar.php

  1. <?php
  2. /**
  3.  * Project: Lunar :: 양력/음력 변환 클래스<br>
  4.  * File:    Lunar.php
  5.  *
  6.  * 이 패키지는 양력/음력간의 변환을 제공한다.
  7.  *
  8.  * 1852년 10월 15일 이전의 양력 날자는 율리우스력으로 취급을 하며, 내부
  9.  * 계산시에 그레고리력으로 변환을 하여 계산을 한다.
  10.  *
  11.  * 제공 되는 기능은 다음과 같다.
  12.  *
  13.  * 1. 양력/음력 변환 API
  14.  * 2. 절기 API
  15.  * 3. 합삭/막 정보 API
  16.  * 4. 세차/월간/일진 API 등
  17.  *
  18.  * 이 변환 API의 유효기간은 다음과 같다.
  19.  *
  20.  * <pre>
  21.  *   * 32bit
  22.  *     + -2087-02-09(음력 -2087-01-01) ~ 6078-01-29(음 6077-12-29)
  23.  *     + -2087-07-05(음력 -2087-05-29) 이전은 계산이 무지 느려짐..
  24.  *
  25.  *   * 64bit
  26.  *     + -4712-02-08 ~ 9999-12-31
  27.  *     + API의 연도 체크가 4자리 까지이므로 10000년 이상은 확인 못함
  28.  *     + 64bit 계산이 가능한 시점까지 가능할 듯..
  29.  *     + 기원전의 경우 Julian date가 BC 4713년 1월 1일 부터이므로
  30.  *       Gregorian calendar 변환이 가능한 BC 4713년 2월 8일부터 가능
  31.  * </pre>
  32.  *
  33.  * 계산 처리 시간상, 과거 2000년전과 미래 100년후의 시간은 왠만하면 웹에서는
  34.  * 사용하는 것을 권장하지 않음!
  35.  *
  36.  * 참고!
  37.  *
  38.  * oops\KASI_Lunar pear package를 설치한 후에, KASI_Lunar.php 를 include 하면,
  39.  * 내부적으로 1391-02-05 ~ 2050-12-31 기간은 천문과학연구원의 음양력 DB를 이용하여
  40.  * 처리를 한다.
  41.  *
  42.  * 주의!
  43.  *
  44.  * Lunar package는 2가지 라이센스를 가지고 있다. Lunar 패키지의
  45.  * Core API (Lunar/Lunar_API.php)는 고영창님의 '진짜만세력' 코드를 PHP로
  46.  * 포팅한 것으로, 고영창님에게 라이센스가 있으며, front end API(Lunar.php)는
  47.  * 김정균이 작성한 코드들로 BSD license를 따른다.
  48.  *
  49.  * @category    Calendar
  50.  * @package     oops\Lunar
  51.  * @author      JoungKyun.Kim <http://oops.org>
  52.  * @copyright   (c) 2024, OOPS.org
  53.  * @license     BSD (Lunar.php) And 고영창(Lunar/Lunar_API.php)
  54.  * @link        https://github.com/OOPS-ORG-PHP/Lunar
  55.  * @since       File available since release 0.0.1
  56.  * @example     Lunar/tests/test.php Sample code
  57.  * @filesource
  58.  */
  59.  
  60. /**
  61.  * Namespace oops
  62.  */
  63. namespace oops;
  64.  
  65. /**
  66.  * import myException class
  67.  */
  68. require_once 'myException.php';
  69. set_error_handler('myException::myErrorHandler');
  70.  
  71.  
  72. /**
  73.  * import Lunar API
  74.  */
  75. require_once 'Lunar/Lunar_API.php';
  76.  
  77. /**
  78.  * 양력/음력 변환 클래스
  79.  *
  80.  * 이 패키지는 양력/음력간의 변환을 제공한다.
  81.  *
  82.  * 1852년 10월 15일 이전의 양력 날자는 율리우스력으로 취급을 하며, 내부
  83.  * 계산시에 그레고리력으로 변환을 하여 계산을 한다.
  84.  *
  85.  * 제공 되는 기능은 다음과 같다.
  86.  *
  87.  * 1. 양력/음력 변환 API
  88.  * 2. 절기 API
  89.  * 3. 합삭/막 정보 API
  90.  * 4. 세차/월간/일진 API 등
  91.  *
  92.  * 이 변환 API의 유효기간은 다음과 같다.
  93.  *
  94.  * <pre>
  95.  *   * 32bit
  96.  *     + -2087-02-09(음력 -2087-01-01) ~ 6078-01-29(음 6077-12-29)
  97.  *     + -2087-07-05(음력 -2087-05-29) 이전은 계산이 무지 느려짐..
  98.  *
  99.  *   * 64bit
  100.  *     + -4712-02-08 ~ 9999-12-31
  101.  *     + API의 연도 체크가 4자리 까지이므로 10000년 이상은 확인 못함
  102.  *     + 64bit 계산이 가능한 시점까지 가능할 듯..
  103.  *     + 기원전의 경우 Julian date가 BC 4713년 1월 1일 부터이므로
  104.  *       Gregorian calendar 변환이 가능한 BC 4713년 2월 8일부터 가능
  105.  * </pre>
  106.  *
  107.  * 계산 처리 시간상, 과거 2000년전과 미래 100년후의 시간은 왠만하면 웹에서는
  108.  * 사용하는 것을 권장하지 않음!
  109.  *
  110.  * 참고!
  111.  *
  112.  * oops\KASI_Lunar pear package를 설치한 후에, KASI_Lunar.php 를 include 하면,
  113.  * 내부적으로 1391-02-05 ~ 2050-12-31 기간은 천문과학연구원의 음양력 DB를 이용하여
  114.  * 처리를 한다.
  115.  *
  116.  * @package     oops\Lunar
  117.  * @author      JoungKyun.Kim <http://oops.org>
  118.  * @copyright   (c) 2024, OOPS.org
  119.  * @license     BSD (Lunar.php) And 고영창(Lunar/Lunar_API.php)
  120.  * @example     Lunar/tests/test.php Sample code
  121.  */
  122. Class Lunar extends Lunar_API {
  123.     private $KASI null;
  124.  
  125.     // {{{ +-- public version (void)
  126.     /**
  127.      * oops\Lunar package 의 버전을 반환.
  128.      *
  129.      * @access public
  130.      * @return string 
  131.      */
  132.     public function version ({
  133.         # 관리를 위하여 single quote 를 사용할 것!
  134.         return '2.0.2';
  135.     }
  136.     // }}}
  137.  
  138.     // {{{ +-- public (array) toargs ($v, $lunar = fasle)
  139.     /**
  140.      * 입력된 날자 형식을 연/월/일의 멤버를 가지는 배열로 반환한다.
  141.      * 입력된 변수 값은 YYYY-MM-DD 형식으로 변환 된다.
  142.      *
  143.      * 예제:
  144.      * {@example Lunar/tests/sample.php 30 25}
  145.      *
  146.      * @access public
  147.      * @return array 
  148.      *    <pre>
  149.      *        Array
  150.      *        (
  151.      *            [0] => 2013
  152.      *            [1] => 7
  153.      *            [2] => 16
  154.      *        )
  155.      *    </pre>
  156.      * @param string|int날자형식
  157.      *
  158.      *    - unixstmap (1970년 12월 15일 이후부터 가능)
  159.      *    - Ymd or Y-m-d
  160.      *    - null data (현재 시간)
  161.      */
  162.     public function toargs (&$v$lunar false{
  163.         if $v == null {
  164.             $y = (int) date ('Y');
  165.             $m = (int) date ('m');
  166.             $d = (int) date ('d');
  167.         else {
  168.             if is_numeric ($v&& $v 30000000 {
  169.                 // unit stamp ?
  170.                 $y = (int) date ('Y'$v);
  171.                 $m = (int) date ('m'$v);
  172.                 $d = (int) date ('d'$v);
  173.             else {
  174.                 if preg_match ('/^(-?[0-9]{1,4})[\/-]?([0-9]{1,2})[\/-]?([0-9]{1,2})$/'trim ($v)$match) ) {
  175.                     array_shift ($match);
  176.                     list ($y$m$d$match;
  177.                 else {
  178.                     throw new \myException ('Invalid Date Format'E_USER_WARNING);
  179.                     return false;
  180.                 }
  181.             }
  182.  
  183.             // 넘어온 날자가 음력일 경우 아래가 실행되면 측정 날자가 달라질 수 있다.
  184.             if $lunar && $y 1969 && $y 2038 {
  185.                 $fixed mktime (000$m$d$y);
  186.                 $y = (int) date ('Y'$fixed);
  187.                 $m = (int) date ('m'$fixed);
  188.                 $d = (int) date ('d'$fixed);
  189.             else {
  190.                 if $m 12 || $d 31 {
  191.                     throw new \myException ('Invalid Date Format'E_USER_WARNING);
  192.                     return false;
  193.                 }
  194.             }
  195.         }
  196.         $v $this->regdate (array ($y$m$d));
  197.  
  198.         return array ($y$m$d);
  199.     }
  200.     // }}}
  201.  
  202.     // {{{ +-- public (string) human_year ($y)
  203.     /**
  204.      * 연도를 human readable하게 표시
  205.      *
  206.      * 예제:
  207.      * {@example Lunar/tests/sample.php 56 11}
  208.      *
  209.      * @access public
  210.      * @return string   AD/BC type의 연도
  211.      * @param int 연도
  212.      */
  213.     public function human_year ($y{
  214.         if $y {
  215.             $y ($y * -11;
  216.             $t 'BC';
  217.         else
  218.             $t 'AD';
  219.  
  220.         return sprintf ('%s %d'$t$y);
  221.     }
  222.     // }}}
  223.  
  224.     // {{{ +-- public (array) split_date ($date)
  225.     /**
  226.      * YYYY-MM-DD 또는 array ((string) YYYY, (string) MM, (string) DD)
  227.      * 입력값을 * array ((int) $y, (int) $m, (int) $d)으로 변환
  228.      *
  229.      * @access public
  230.      * @return array array ((int) $y, (int) $m, (int) $d)
  231.      * @param array|string
  232.      *      - YYYY-MM-DD
  233.      *      - array ((string) YYYY, (string) MM, (stirng) DD)
  234.      */
  235.     public function split_date ($date{
  236.         if is_array ($date) )
  237.             $date $this->regdate ($date);
  238.  
  239.         $minus ($date[0== '-'true false;
  240.         $date $minus substr ($date1$date;
  241.  
  242.         $r preg_split ('/-/'$date);
  243.         if $minus )
  244.             $r[0*= -1;
  245.  
  246.         foreach ($r as $k => $v )
  247.             $r[$k= (int) $v;
  248.  
  249.         return $r;
  250.     }
  251.     // }}}
  252.  
  253.     // {{{ +-- private (string) regdate ($v)
  254.     /**
  255.      * YYYY-MM-DD 형식의 날자를 반환
  256.      *
  257.      * @access private
  258.      * @return string   YYYY-MM-DD 형식으로 반환
  259.      * @param array     년월일 배열 - array ($year, $month, $day)
  260.      */
  261.     private function regdate ($v{
  262.         list ($year$month$day$v;
  263.  
  264.         return sprintf (
  265.             '%d-%s%d-%s%d',
  266.             $year,
  267.             ($month 10 '0' '',
  268.             (int) $month,
  269.             ($day 10 '0' '',
  270.             (int) $day
  271.         );
  272.     }
  273.     // }}}
  274.  
  275.     // {{{ +-- public (bool) is_leap ($y, $julian = false)
  276.     /**
  277.      * 윤년 체크
  278.      *
  279.      * 예제:
  280.      * {@example Lunar/tests/sample.php 68 14}
  281.      *
  282.      * @access public
  283.      * @return bool 
  284.      * @param int 년도
  285.      * @param bool Julian 여부
  286.      *  <p>
  287.      *  1582년 이전은 Julian calender로 판단하여 이 값이
  288.      *  false라도 율리우스력으로 간주하여 판단한다. (sinse 1.0.1)
  289.      *  </p>
  290.      */
  291.     public function is_leap ($y$julian false{
  292.         // Julian의 윤년은 4로 나누어지면 된다.
  293.         if $julian || $y 1583 )
  294.             return ($y 4false true;
  295.  
  296.         if ( ($y 400== )
  297.             return true;
  298.  
  299.         if ( ($y 4== && ($y 100!= )
  300.             return true;
  301.  
  302.         return false;
  303.     }
  304.     // }}}
  305.  
  306.     // {{{ +-- public (bool) is_gregorian ($y, $m, $d = 1)
  307.     /**
  308.      * 해당 날자가 gregorian 범위인지 체크
  309.      *
  310.      * @access public
  311.      * @return bool 
  312.      * @param int 연도
  313.      * @param int 
  314.      * @param int 
  315.      */
  316.     public function is_gregorian ($y$m$d 1{
  317.         if (int) $m 10 )
  318.             $m '0' . (int) $m;
  319.         if (int) $d 10 )
  320.             $d '0' . (int) $d;
  321.  
  322.         $chk $y $m $d;
  323.  
  324.         if $chk 15821015 )
  325.             return false;
  326.  
  327.         return true;
  328.     }
  329.     // }}}
  330.  
  331.     // {{{ +-- private (string) gregorian2julian ($v)
  332.     /**
  333.      * 그레고리력을 율리안력으로 변환
  334.      *
  335.      * @access private
  336.      * @return stdClass 
  337.      *
  338.      *    <pre>
  339.      *    stdClass Object
  340.      *    (
  341.      *        [fmt] => 2013-06-09          // YYYY-MM-DD 형식의 Julian 날자
  342.      *        [year] => 2013               // 연도
  343.      *        [month] => 6                 // 월
  344.      *        [day] => 9                   // 일
  345.      *        [week] => 화                 // 요일
  346.      *    )
  347.      *    </pre>
  348.      *
  349.      * @param array|intGregorian 연월일 배열 or Julian date count
  350.      */
  351.     private function gregorian2julian ($v{
  352.         if is_array ($v) ) {
  353.             $d $this->regdate ($v);
  354.             list ($y$m$d$this->split_date ($d);
  355.  
  356.             $v $this->cal2jd (array ($y$m$d));
  357.         }
  358.  
  359.         if extension_loaded ('calendar') ) {
  360.             $r = (object) cal_from_jd ($vCAL_JULIAN);
  361.             if $r->year )
  362.                 $r->year++;
  363.  
  364.             return (object) array (
  365.                 'fmt'   => $this->regdate (array ($r->year$r->month$r->day)),
  366.                 'year'  => $r->year,
  367.                 'month' => $r->month,
  368.                 'day'   => $r->day,
  369.                 'week'  => $r->dow
  370.             );
  371.         }
  372.  
  373.         if is_float ($v) ) {
  374.             list ($Z$Fpreg_split ('/\./'$v);
  375.         else {
  376.             $Z $v;
  377.             $F 0;
  378.         }
  379.  
  380.         if $v 2299161 )
  381.             $A $Z;
  382.         else {
  383.             $alpha = (int) ($Z 1867216.25 36524.25);
  384.             $A $Z $alpha - (int) ($alpha 4);
  385.         }
  386.  
  387.         $B $A 1524;
  388.         $C = (int) (($B 122.1365.25);
  389.         $D = (int) (365.25 $C);
  390.         $E = (int) ( ($B $D30.6001);
  391.  
  392.         $day $B $D - (int) (30.6001 $E$F;
  393.         $month ($E 14$E $E 13;
  394.         $year $C 4715;
  395.         if $month )
  396.             $year--;
  397.  
  398.         $week ($v 1.57;
  399.  
  400.         return (object) array (
  401.             'fmt'   => $this->regdate (array ($year$month$day)),
  402.             'year'  => $year,
  403.             'month' => $month,
  404.             'day'   => $day,
  405.             'week'  => $week
  406.         );
  407.     }
  408.     // }}}
  409.  
  410.     // {{{ +-- private mod ($x, $y)
  411.     private function mod ($x$y{
  412.         return ($x $y $y$y;
  413.     }
  414.     // }}}
  415.  
  416.     // {{{ +-- private (string) julian2gregorian ($v)
  417.     /**
  418.      * 율리안력을 그레고리안역으로 변환
  419.      *
  420.      * @access private
  421.      * @return stdClass 
  422.      *
  423.      *    <pre>
  424.      *    stdClass Object
  425.      *    (
  426.      *        [fmt]   => 2013-06-09        // YYYY-MM-DD 형식의 Julian 날자
  427.      *        [year]  => 2013              // 연도
  428.      *        [month] => 6                 // 월
  429.      *        [day]   => 9                 // 일
  430.      *        [week]  => 화                // 요일
  431.      *    )
  432.      *    </pre>
  433.      *
  434.      * @param array|intJulian 연월일 배열 or Julian date count
  435.      */
  436.     private function julian2gregorian ($jd$pure false{
  437.         if is_array ($jd) ) {
  438.             list ($y$m$d$this->split_date ($jd);
  439.             $jd $this->cal2jd (array ($y$m$d)true);
  440.         }
  441.  
  442.         if extension_loaded ('calendar'&& $pure == false {
  443.             $r = (object) cal_from_jd ($jdCAL_GREGORIAN);
  444.             if $r->year )
  445.                 $r->year++;
  446.  
  447.             return (object) array (
  448.                 'fmt'   => $this->regdate (array ($r->year$r->month$r->day)),
  449.                 'year'  => $r->year,
  450.                 'month' => $r->month,
  451.                 'day'   => $r->day,
  452.                 'week'  => $r->dow
  453.             );
  454.         }
  455.  
  456.         // https://en.wikipedia.org/wiki/Julian_day#Gregorian_calendar_from_Julian_day_number
  457.         // 01-01-02 부터 이전은 맞지 않는다 --;
  458.         #$f = (int) $jd + 1401;
  459.         #$f = (int) ($f + (((4 * $jd + 274277) / 146097) * 3) / 4 - 38);
  460.         #$e = 4 * $f + 3;
  461.         #$g = (int) (($e % 1461) / 4);
  462.         #$h = 5 * $g + 2;
  463.         #$day = (int) (($h % 153) / 5 + 1);
  464.         #$month = (int) ((($h / 153 + 2) % 12) + 1);
  465.         #$year = (int) ($e / 1461 - 4716 + (12 + 2 - $month) / 12);
  466.  
  467.         // http://www.fourmilab.ch/documents/calendar/
  468.         $wjd floor ($jd -  0.50.5;
  469.         # GREGORIAN_EPOCH 1721425.5
  470.         $depoch $wjd 1721425.5;
  471.         $quadricent floor ($depoch 146097);
  472.         $dqc $this->mod ($depoch146097);
  473.         $cent floor ($dqc 36524);
  474.         $dcent $this->mod ($dqc36524);
  475.         $quad floor ($dcent 1461);
  476.         $dquad $this->mod ($dcent1461);
  477.         $yindex floor ($dquad 365);
  478.  
  479.         $year ($quadricent 400($cent 100($quad 4$yindex;
  480.         if ($cent == || $yindex == 4) )
  481.             $year++;
  482.     
  483.         $yearday $wjd $this->cal2jd (array ($year11));
  484.         $leapadj (($wjd $this->cal2jd (array ($year31)))
  485.                     ? ($this->is_leap ($year2));
  486.         $month floor (((($yearday $leapadj12373367);
  487.         $day ceil ($wjd $this->cal2jd (array ($year$month1))) 1;
  488.  
  489.         $week ($jd 1.57;
  490.  
  491.         return (object) array (
  492.             'fmt'   => $this->regdate (array ($year$month$day)),
  493.             'year'  => $year,
  494.             'month' => $month,
  495.             'day'   => $day,
  496.             'week'  => $week
  497.         );
  498.     }
  499.     // }}}
  500.  
  501.     // {{{ +-- private (int) cal2jd_pure ($v, $julian = false)
  502.     /**
  503.      * Gregorian 날자를 Julian date로 변환 (by PURE PHP CODE)
  504.      *
  505.      * http://new.astronote.org/bbs/board.php?bo_table=prog&wr_id=29929
  506.      * 1. Y는 해당년도, M는 월(1월=1,2월=2), D는 해당 월의 날짜이다.
  507.      *    D는 시간값도 포함한 소수값으로 생각하자. 가령 3일 12시 UT라면
  508.      *    D=3.5이다.
  509.      * 2. M>2인 경우 Y,M은 변경하지 않는다. M = 1 또는 2인 경우 Y=Y-1,
  510.      *    M=M+12로 계산한다.
  511.      * 3. 그레고리력(Gregorian Calendar)의 경우 아래처럼 계산한다.
  512.      *    A = INT(Y/100), B = 2 – A + INT(A/4)
  513.      *    여기서 INT는 ()안에 들어간 값을 넘지않는 가장 큰 정수이다.
  514.      *    율리우스력(Julian Calendar)의 경우 B=0이다.
  515.      * 4. JD는 다음과 같이 계산된다.
  516.      *    JD = INT(365.25(Y+4716)) + INT(30.6001(M+1)) + D + B – 1524.5
  517.      *    여기서 30.6001은 정확히는 30.6을 써야한다. 하지만 컴퓨터 계산시
  518.      *    10.6이여 하는데 10.599999999 이런식으로 표현되는 경우가 발생하면
  519.      *    INT(10.6)과 INT(10.5999..)의 결과가 달라진다. 이 문제 대해 대처
  520.      *    하기 위해 30.6001을 사용한 것이다. 이러한 에러를 Round-off Error
  521.      *    라고 불린다.
  522.      *
  523.      * @access private
  524.      * @return int Julian date
  525.      * @param array 연월일 배열 : array ($y, $m, $d)
  526.      */
  527.     private function cal2jd_pure ($v$julian false{
  528.         list ($y$m$d$v;
  529.  
  530.         if $m <= {
  531.             $y--;
  532.             $m += 12;
  533.         }
  534.  
  535.         $A = (int) ($y 100);
  536.         $B $julian $A + (int) ($A 4);
  537.         $C = (int) (365.25 ($y 4716));
  538.         $D = (int) (30.6001 ($m 1));
  539.         return ceil ($C $D $d $B 1524.5);
  540.     }
  541.     // }}}
  542.  
  543.     // {{{ +-- private (int) cal2jd_ext ($v, $julian = false)
  544.     /**
  545.      * Gregorian 날자를 Julian date로 변환 (by Calendar Extension)
  546.      *
  547.      * @access private
  548.      * @return int Julian date
  549.      * @param array 연월일 배열 : array ($y, $m, $d)
  550.      */
  551.     private function cal2jd_ext ($v$julian false{
  552.         list ($y$m$d$v;
  553.  
  554.         $old date_default_timezone_get ();
  555.         date_default_timezone_set ('UTC');
  556.  
  557.         $func $julian 'JulianToJD' 'GregorianToJD';
  558.         if $y )
  559.             $y--;
  560.         $r $func ((int) $m(int) $d(int) $y);
  561.  
  562.         date_default_timezone_set ($old);
  563.         return $r;
  564.     }
  565.     // }}}
  566.  
  567.     // {{{ +-- public (int) cal2jd ($v)
  568.     /**
  569.      * Gregorian 날자를 Julian date로 변환
  570.      *
  571.      * @access public
  572.      * @return int Julian date
  573.      * @param array 연월일 배열 : array ($y, $m, $d)
  574.      */
  575.     public function cal2jd ($v$julian false{
  576.         if extension_loaded ('calendar') )
  577.             return $this->cal2jd_ext ($v$julian);
  578.  
  579.         return $this->cal2jd_pure ($v$julian);
  580.     }
  581.     // }}}
  582.  
  583.     // {{{ +-- private (string) toutc ($v)
  584.     /**
  585.      * Localtime을 UTC로 변환
  586.      *
  587.      * @access private
  588.      * @return string YYYY-MM-DD-HH-II-SS
  589.      * @param string date format (YYYY-MM-DD HH:II:SS)
  590.      */
  591.     private function toutc ($v{
  592.         $t strtotime ($v);
  593.         $old date_default_timezone_get ();
  594.         date_default_timezone_set ('UTC');
  595.         $r date ('Y-m-d-H-i-s'$t);
  596.         date_default_timezone_set ($old);
  597.  
  598.         return $r;
  599.     }
  600.     // }}}
  601.  
  602.     // {{{ +-- private (int) to_utc_julian ($v)
  603.     /**
  604.      * 합삭/망 절기 시간을 UTC로 변환 후, Julian date로 표현
  605.      *
  606.      * @access private
  607.      * @return int 
  608.      * @param string data format (YYYY-MM-DD HH:II:SS)
  609.      */
  610.     private function to_utc_julian ($v{
  611.         $buf $this->toutc ($v);
  612.         list ($y$m$d$h$i$s$this->split_date ($buf);
  613.  
  614.         $chk $y $m $d;
  615.  
  616.         //$julian = ( $chk < 18451015 ) ? $true : false;
  617.         $j $this->cal2jd (array ($y$m$d)$julian);
  618.  
  619.         if ( ($h 12{
  620.             $h 11 $h;
  621.             $i 60 $i;
  622.             $buf (($h 3600 $i 6086400* -1;
  623.         else
  624.             $buf (($h 123600 $i 6086400;
  625.  
  626.         return $j $buf;
  627.     }
  628.     // }}}
  629.  
  630.     // {{{ +-- private (array) fix_calendar ($y, $m, $d)
  631.     /**
  632.      * 1582년 10월 15일 이전의 date를 julian calendar로 변환
  633.      *
  634.      * @access private
  635.      * @return array 년월일 배열 (array ($y, $m, $d))
  636.      * @param int year
  637.      * @param int month
  638.      * @param int day
  639.      */
  640.     private function fix_calendar ($y$m$d{
  641.         if $m 10 )
  642.             $m '0' $m;
  643.         if $d 10 )
  644.             $d '0' $d;
  645.  
  646.         # 15821005 ~ 15821014 까지는 gregorian calendar에서는 존재
  647.         # 하지 않는다. 그러므로, 이 기간의 날자는 julian calendar
  648.         # 와 매치되는 날자로 변경한다. (10씩 빼준다.
  649.         $chk $y $m $d;
  650.         if $chk 15821004 && $chk 15821015 {
  651.             $julian $this->cal2jd (array ($y(int) $m(int) $d));
  652.             $julian -= 10;
  653.             $r $this->julian2gregorian ($julian);
  654.             list ($y$m$darray ($r->year$r->month$r->day);
  655.         }
  656.  
  657.         # 15821005 보다 과거의 날자는 gregorian calendar가 없다.
  658.         # 그러므로 julian calendar로 표현한다.
  659.         if $this->is_gregorian ($y(int) $m(int) $d=== false {
  660.             $r $this->julian2gregorian (array ($y(int) $m(int) $d));
  661.             list ($y$m$darray ($r->year$r->month$r->day);
  662.         }
  663.  
  664.         return array ($y$m$d);
  665.     }
  666.     // }}}
  667.  
  668.     // {{{ +-- public (object) tolunar ($v = null)
  669.     /**
  670.      * 양력 날자를 음력으로 변환
  671.      *
  672.      * 진짜 만세력은 1582/10/15(Gregorian calendar의 시작) 이전의 날자
  673.      * 역시 Gregorian으로 표기를 한다. 그러므로 Calendar의 오류로 보일
  674.      * 수도 있다. (실제로는 계산상의 오류는 없다고 봐야 한다.)
  675.      *
  676.      * 이런 부분을 보정하기 위하여, tolunar method는 1582/10/04 까지의
  677.      * 날자는 julian calendar로 변환을 하여 음력날자를 구한다. 이로 인
  678.      * 하여 1582/10/15 이전의 음력 날자는 original 진짜 만세력과 다른
  679.      * 값을 가지게 된다.)
  680.      *
  681.      * 이렇게 표현될 경우, 천문우주 지식정보의 값과 비슷하게 나올 수는
  682.      * 있으나, 평달/큰달 계산은 진짜 만세력의 것을 이용하므로 오차는
  683.      * 발생할 수 있다.
  684.      * http://astro.kasi.re.kr/Life/ConvertSolarLunarForm.aspx?MenuID=115
  685.      *
  686.      * 2.0 부터는 이러한 오차를 줄이기 위하여 oops\KASI_Lunar package가
  687.      * 설치되어 있을 경우, 1392-02-05 ~ 2050-12-31 기간에 대해서는
  688.      * 천문과학연구원의 데이터를 이용할 수 있도록 지원한다.
  689.      *
  690.      * 예제:
  691.      * {@example Lunar/tests/sample.php 83 35}
  692.      *
  693.      * @access public
  694.      * @return stdClass    음력 날자 정보 반환
  695.      *
  696.      *    <pre>
  697.      *    stdClass Object
  698.      *    (
  699.      *        [fmt] => 2013-06-09          // YYYY-MM-DD 형식의 음력 날자
  700.      *        [dangi] => 4346              // 단기
  701.      *        [hyear] => AD 2013           // AD/BC 형식의 연도
  702.      *        [year] => 2013               // 연도
  703.      *        [month] => 6                 // 월
  704.      *        [day] => 9                   // 일
  705.      *        [leap] =>                    // 음력 윤달 여부
  706.      *        [largemonth] => 1            // 평달/큰달 여부
  707.      *        [week] => 화                 // 요일
  708.      *        [hweek] => 火                // 한자 요일
  709.      *        [unixstamp] => 1373900400    // unixstamp (양력 날자)
  710.      *        [ganji] => 계사              // 세차(년)
  711.      *        [hganji] => 癸巳             // 한자 세차
  712.      *        [gan] => 계                  // 세차 10간
  713.      *        [hgan] => 癸                 // 세차 한자 10간
  714.      *        [ji] => 사                   // 세차 12지
  715.      *        [hji] => 巳                  // 세차 한자 12지
  716.      *        [ddi] => 뱀                  // 띠
  717.      *    )
  718.      *    </pre>
  719.      *
  720.      * @param int|string  날자형식
  721.      *    - unixstmap (1970년 12월 15일 이후부터 가능)
  722.      *    - Ymd or Y-m-d
  723.      *    - null data (현재 시간)
  724.      *    - 1582년 10월 15일 이전의 날자는 율리우스력의 날자로 취급함.
  725.      */
  726.     public function tolunar ($v null{
  727.         list ($y$m$d$this->toargs ($v);
  728.         #printf ("** %4s.%2s.%2s ... ", $y, $m, $d);
  729.  
  730.         $kasi false;
  731.         $cdate preg_replace ('/-/'''$v);
  732.         // 1391-02-05 ~ 2050-12-31 까지는 KASI data로 처리를 한다.
  733.         if $cdate 13910204 && $cdate 20510101 {
  734.             if class_exists ('oops\KASI\Lunar') ) {
  735.                 $kasi true;
  736.                 if $this->KASI == null )
  737.                     $this->KASI new \oops\KASI\Lunar;
  738.  
  739.                 # Lunar_KASI::tolunar method 는 1391-02-05 ~ 2050-12-31 구간을 벗어나면 Exception 을
  740.                 # 발생 시킨다. 그러므로 예외 처리가 필요하다. 하지만 여기서는 상단에 이미 에외 구간을
  741.                 # 제한하고 있어, 딱히 예외 처리를 할 필요는 없다.
  742.                 $r $this->KASI->tolunar ($v);
  743.                 if $r === false )
  744.                     return false;
  745.  
  746.                 $year   $r->year;
  747.                 $month  $r->month;
  748.                 $day    $r->day;
  749.                 $leap   $r->leap;
  750.                 $lmonth $r->lmoon;
  751.                 $w      $r->week;
  752.  
  753.                 unset ($r);
  754.                 $r array ($year$month$day);
  755.             }
  756.         }    
  757.  
  758.         if $kasi === false {
  759.             list ($y$m$d$this->fix_calendar ($y$m$d);
  760.             #printf ("%4s.%2s.%2s<br>", $y, $m, $d);
  761.  
  762.             $r $this->solartolunar ($y$m$d);
  763.             list ($year$month$day$leap$lmonth$r;
  764.  
  765.             $w $this->getweekday ($y$m$d);
  766.         }
  767.  
  768.         $k1 ($year 610;
  769.         $k2 ($year 812;
  770.  
  771.         if $k1 $k1 += 10;
  772.         if $k2 $k2 += 12;
  773.  
  774.         return (object) array (
  775.             'fmt'        => $this->regdate ($r),
  776.             'dangi'      => $year 2333,
  777.             'hyear'      => $this->human_year ($year),
  778.             'year'       => $year,
  779.             'month'      => $month,
  780.             'day'        => $day,
  781.             'leap'       => $leap,
  782.             'largemonth' => $lmonth,
  783.             'week'       => $this->week[$w],
  784.             'hweek'      => $this->hweek[$w],
  785.             'unixstamp'  => mktime (000$m$d$y),
  786.             'ganji'      => $this->gan[$k1$this->ji[$k2],
  787.             'hganji'     => $this->hgan[$k1$this->hji[$k2],
  788.             'gan'        => $this->gan[$k1],
  789.             'hgan'       => $this->hgan[$k1],
  790.             'ji'         => $this->ji[$k2],
  791.             'hji'        => $this->hji[$k2],
  792.             'ddi'        => $this->ddi[$k2]
  793.         );
  794.     }
  795.     // }}}
  796.  
  797.     // {{{ +-- public (object) tosolar ($v = null, $leap = false)
  798.     /**
  799.      * 음력 날자를 양력으로 변환.
  800.      *
  801.      * 구하는 음력월이 윤달인지 여부를 알 수 없을 경우, tosolar method
  802.      * 를 실행하여 얻은 양력 날자를 다시 tolunar로 변환하여 비교하여
  803.      * 동일하지 않다면, 윤달 파라미터 값을 주고 다시 구해야 한다!
  804.      *
  805.      * 진짜 만세력은 Gregorian으로 표기를 하기 때문에, 양력 1582-10-15
  806.      * 이전의 경우에는 return object의 julian member 값으로 비교를 해야
  807.      * 한다.
  808.      *
  809.      * 예제:
  810.      * {@example Lunar/tests/sample.php 119 42}
  811.      *
  812.      * @access public
  813.      * @return stdClass    양력 날자 정보 object 반환
  814.      *
  815.      *    <pre>
  816.      *    stdClass Object
  817.      *    (
  818.      *        [jd] => 2456527             // Julian Date Count
  819.      *        [fmt] => 2013-07-16         // YYYY-MM-DD 형식의 양력 날자 (15821015 이전은 율리우스력)
  820.      *        [gregory] => 2013-07-16     // Gregory Calendar
  821.      *        [julian] => 2013-08-09      // Julian Calendar
  822.      *        [dangi] => 4346             // 단기 (양력)
  823.      *        [hyear] => AD 2013          // AD/BC 형식 년도
  824.      *        [year] => 2013              // 양력 연도
  825.      *        [month] => 7                // 월
  826.      *        [day] => 16                 // 일
  827.      *        [week] => 화                // 요일
  828.      *        [hweek] => 火               // 한자 요일
  829.      *        [unixstamp] => 1373900400   // unixstamp (양력)
  830.      *        [ganji] => 계사             // 세차
  831.      *        [hganji] => 癸巳            // 세차 한자
  832.      *        [gan] => 계                 // 세차 10간
  833.      *        [hgan] => 癸                // 세차 한자 10간
  834.      *        [ji] => 사                  // 세차 12지
  835.      *        [hji] => 巳                 // 세차 한자 12지
  836.      *        [ddi] => 뱀                 // 띠
  837.      *    )
  838.      *    </pre>
  839.      *
  840.      * @param int|string날자형식
  841.      *
  842.      *    - unixstmap (1970년 12월 15일 이후부터 가능)
  843.      *    - Ymd or Y-m-d
  844.      *    - null data (현재 시간)
  845.      *
  846.      * @param bool 윤달여부
  847.      */
  848.     public function tosolar ($v null$leap false{
  849.         list ($y$m$d$this->toargs ($vtrue);
  850.  
  851.         $kasi false;
  852.         $cdate preg_replace ('/-/'''$v);
  853.         // 1391-01-01 ~ 2050-12-31 까지는 KASI data로 처리를 한다.
  854.         if $cdate 13910101 && $cdate 20501119 {
  855.             if class_exists ('oops\KASI\Lunar') ) {
  856.                 $kasi true;
  857.                 if $this->KASI == null )
  858.                     $this->KASI new \oops\KASI\Lunar;
  859.  
  860.                 # Lunar_KASI::tosolar method 는 1391-01-01 ~ 2050-12-31 구간을 벗어나면 Exception 을
  861.                 # 발생 시킨다. 그러므로 예외 처리가 필요하다. 하지만 여기서는 상단에 이미 에외 구간을
  862.                 # 제한하고 있어, 딱히 예외 처리를 할 필요는 없다.
  863.                 $r $this->KASI->tosolar ($v$leap);
  864.                 if $r === false )
  865.                     return false;
  866.  
  867.                 $year  $r->year;
  868.                 $month $r->month;
  869.                 $day   $r->day;
  870.                 $w     $r->week;
  871.  
  872.                 $jdate $r->jd
  873.                 $fmt   $r->fmt;
  874.  
  875.                 if $r->jd 2299160{
  876.                     $j    $this->gregorian2julian ($r->jd);
  877.                     $jfmt $j->fmt;
  878.                     $gfmt $r->fmt;
  879.                 else {
  880.                     $jfmt $r->fmt;
  881.                     $g    $this->julian2gregorian ($r->jd);
  882.                     $gfmt $g->fmt;
  883.                 }
  884.             }
  885.         }
  886.  
  887.         if $kasi === false {
  888.             $r $this->lunartosolar ($y$m$d$leap);
  889.             list ($year$month$day$r;
  890.  
  891.             $w $this->getweekday ($year$month$day);
  892.  
  893.             $jdate $this->cal2jd ($r);
  894.             //$julian = $this->gregorian2julian ($r);
  895.             $julian $this->gregorian2julian ($jdate);
  896.             $jfmt   $julian->fmt;
  897.             $gfmt   $this->regdate ($r);
  898.             $fmt ($jdate 2299161$jfmt $gfmt;
  899.         }
  900.  
  901.         $k1 ($y 610;
  902.         $k2 ($y 812;
  903.  
  904.         if $k1 $k1 += 10;
  905.         if $k2 $k2 += 12;
  906.  
  907.         return (object) array (
  908.             'jd'         => $jdate,
  909.             'fmt'        => $fmt,
  910.             'gregory'    => $gfmt,
  911.             'julian'     => $jfmt,
  912.             'dangi'      => $year 2333,
  913.             'hyear'      => $this->human_year ($year),
  914.             'year'       => $year,
  915.             'month'      => $month,
  916.             'day'        => $day,
  917.             'week'       => $this->week[$w],
  918.             'hweek'      => $this->hweek[$w],
  919.             'unixstamp'  => mktime (000$month$day$year),
  920.             'ganji'      => $this->gan[$k1$this->ji[$k2],
  921.             'hganji'     => $this->hgan[$k1$this->hji[$k2],
  922.             'gan'        => $this->gan[$k1],
  923.             'hgan'       => $this->hgan[$k1],
  924.             'ji'         => $this->ji[$k2],
  925.             'hji'        => $this->hji[$k2],
  926.             'ddi'        => $this->ddi[$k2]
  927.         );
  928.     }
  929.     // }}}
  930.  
  931.     // {{{ +-- public (object) dayfortune ($v = null)
  932.     /**
  933.      * 세차(년)/월건(월)/일진(일) 데이터를 구한다.
  934.      *
  935.      * 예제:
  936.      * {@example Lunar/tests/sample.php 163 56}
  937.      *
  938.      * @access public
  939.      * @return stdClass 
  940.      *
  941.      *    <pre>
  942.      *    stdClass Object
  943.      *    (
  944.      *        [data] => stdClass Object
  945.      *            (
  946.      *                 [y] => 29           // 세차 index
  947.      *                 [m] => 55           // 월건 index
  948.      *                 [d] => 19           // 일진 index
  949.      *            )
  950.      *
  951.      *        [year] => 계사               // 세차 값
  952.      *        [month] => 기미              // 월건 값
  953.      *        [day] => 계미                // 일진 값
  954.      *        [hyear] => 癸巳              // 한자 세차 값
  955.      *        [hmonth] => 己未             // 한자 월건 값
  956.      *        [hday] => 癸未               // 한자 일진 값
  957.      *    )
  958.      *    </pre>
  959.      *
  960.      * @param int|string날자형식
  961.      *
  962.      *     - unixstmap (1970년 12월 15일 이후부터 가능)
  963.      *     - Ymd or Y-m-d
  964.      *     - null data (현재 시간)
  965.      *     - 1582년 10월 15일 이전의 날자는 율리우스력의 날자로 취급함.
  966.      */
  967.     public function dayfortune ($v null{
  968.         list ($y$m$d$this->toargs ($v);
  969.         list ($y$m$d$this->fix_calendar ($y$m$d);
  970.  
  971.         list ($so24$year$month$day$hour)
  972.             = $this->sydtoso24yd ($y$m$d10);
  973.  
  974.         return (object) array (
  975.             'data' => (object) array ('y' => $year'm' => $month'd' => $day),
  976.             'year' => $this->ganji[$year],
  977.             'month' => $this->ganji[$month],
  978.             'day' => $this->ganji[$day],
  979.             'hyear' => $this->hganji[$year],
  980.             'hmonth' => $this->hganji[$month],
  981.             'hday' => $this->hganji[$day],
  982.         );
  983.     }
  984.     // }}}
  985.  
  986.     // {{{ +-- public (object) s28day ($v = null)
  987.     /**
  988.      * 특정일의 28수를 구한다.
  989.      *
  990.      * 예제:
  991.      * {@example Lunar/tests/sample.php 221 35}
  992.      *
  993.      * @access public
  994.      * @return stdClass 
  995.      *
  996.      *    <pre>
  997.      *    stdClass Object
  998.      *    (
  999.      *        [data] => 5    // 28수 index
  1000.      *        [k] => 미      // 한글 28수 값
  1001.      *        [h] => 尾      // 한자 28수 값
  1002.      *    )
  1003.      *    </pre>
  1004.      *
  1005.      * @param int|string  날자형식
  1006.      *
  1007.      *     - unixstmap (1970년 12월 15일 이후부터 가능)
  1008.      *     - Ymd or Y-m-d
  1009.      *     - null data (현재 시간)
  1010.      *     - 1582년 10월 15일 이전의 날자는 율리우스력의 날자로 취급함.
  1011.      *     - Recursion s28day return value:<br>
  1012.      *       loop에서 s28day method를 반복해서 호출할 경우 return value를 이용할
  1013.      *       경우, return value의 index값을 이용하여 계산을 하지 않아 속도가 빠름.
  1014.      */
  1015.     public function s28day ($v null{
  1016.         if is_object ($v) ) {
  1017.             $r $v->data 1;
  1018.             if $r >= 28 )
  1019.                 $r %= 28;
  1020.  
  1021.             goto return_data;
  1022.         }
  1023.  
  1024.         list ($y$m$d$this->toargs ($v);
  1025.         list ($y$m$d$this->fix_calendar ($y$m$d);
  1026.         $r $this->get28sday ($y$m$d);
  1027.  
  1028.         return_data:
  1029.  
  1030.         return (object) array (
  1031.             'data' => $r,
  1032.             'k' => $this->s28days_hangul[$r],
  1033.             'h' => $this->s28days[$r]
  1034.         );
  1035.     }
  1036.     // }}}
  1037.  
  1038.     // {{{ +-- public (array) seasondate ($v = null)
  1039.     /**
  1040.      * 해당 양력일에 대한 음력 월의 절기 시간 구하기
  1041.      *
  1042.      * 2.0.1 부터는 KASI-Lunar 2.0.0 이상이 설치 되어 있을 경우,
  1043.      * 천문과학연구원의 2004~2026 의 절기 데이터를 이용한다.
  1044.      *
  1045.      * 예제:
  1046.      * {@example Lunar/tests/sample.php 257 52}
  1047.      *
  1048.      * @access public
  1049.      * @return stdClass   현달 초입/중기와 다음달 초입 데이터 반환
  1050.      *
  1051.      *    <pre>
  1052.      *    stdClass Object
  1053.      *    (
  1054.      *        [center] => stdClass Object      // 이번달 초입 데이터
  1055.      *            (
  1056.      *                [name] => 소서              // 절기 이름
  1057.      *                [hname] => 小暑             // 절기 한자 이름
  1058.      *                [hyear] => AD 2013          // AD/BC 형식 연도
  1059.      *                [year] => 2013              // 초입 연도
  1060.      *                [month] => 7                // 초입 월
  1061.      *                [day] => 7                  // 초입 일
  1062.      *                [hour] => 7                 // 초입 시간
  1063.      *                [min] => 49                 // 초입 분
  1064.      *                [julian] => 2456480.4506944 // Julian date (UTC)
  1065.      *            )
  1066.      *
  1067.      *        [ccenter] => stdClass Object     // 이번달 중기 데이터
  1068.      *            (
  1069.      *                [name] => 대서              // 절기 이름
  1070.      *                [hname] => 大暑             // 절기 한자 이름
  1071.      *                [hyear] => AD 2013          // AD/BC 형식 연도
  1072.      *                [year] => 2013              // 중기 연도
  1073.      *                [month] => 7                // 중기 월
  1074.      *                [day] => 23                 // 중기 일
  1075.      *                [hour] => 1                 // 중기 시간
  1076.      *                [min] => 11                 // 중기 분
  1077.      *                [julian] => 2456496.1743056 // Julian date (UTC)
  1078.      *            )
  1079.      *
  1080.      *        [nenter] => stdClass Object      // 다음달 초입 데이터
  1081.      *            (
  1082.      *                [name] => 입추              // 절기 이름
  1083.      *                [hname] => 立秋             // 절기 한자 이름
  1084.      *                [hyear] => AD 2013          // AD/BC 형식 연도
  1085.      *                [year] => 2013              // 초입 연도
  1086.      *                [month] => 8                // 초입 월
  1087.      *                [day] => 7                  // 초입 일
  1088.      *                [hour] => 17                // 초입 시간
  1089.      *                [min] => 36                 // 초입 분
  1090.      *                [julian] => 2456511.8583333 // Julian date (UTC)
  1091.      *            )
  1092.      *    )
  1093.      *    </pre>
  1094.      *
  1095.      * @param int|string  날자형식
  1096.      *
  1097.      *   - unixstmap (1970년 12월 15일 이후부터 가능)
  1098.      *   - Ymd or Y-m-d
  1099.      *   - null data (현재 시간
  1100.      *   - 1582년 10월 15일 이전의 날자는 율리우스력의 날자로 취급함.
  1101.      */
  1102.     public function seasondate ($v null{
  1103.         list ($y$m$d$this->toargs ($v);
  1104.         list ($y$m$d$this->fix_calendar ($y$m$d);
  1105.  
  1106.         list (
  1107.             $inginame$ingiyear$ingimonth$ingiday$ingihour$ingimin,
  1108.             $midname$midyear$midmonth$midday$midhour$midmin,
  1109.             $outginame$outgiyear$outgimonth$outgiday$outgihour$outgimin
  1110.         $this->solortoso24 ($y$m2010);
  1111.  
  1112.         $j_ce $this->to_utc_julian (
  1113.             sprintf (
  1114.                 '%s %s:%s:00',
  1115.                 $this->regdate (array ($ingiyear$ingimonth$ingiday)),
  1116.                 $ingihour 10 '0' $ingihour $ingihour,
  1117.                 $ingimin 10 '0' $ingimin $ingimin
  1118.             )
  1119.         );
  1120.  
  1121.         // 1852-10-15 이전이면 julian으로 변경
  1122.         if $this->is_gregorian ($ingiyear$ingimonth$ingiday=== false {
  1123.             $r $this->gregorian2julian (array ($ingiyear$ingimonth$ingiday));
  1124.             $ingiyear  $r->year;
  1125.             $ingimonth $r->month;
  1126.             $ingiday   $r->day;
  1127.         }
  1128.  
  1129.         $j_cc $this->to_utc_julian (
  1130.             sprintf (
  1131.                 '%s %s:%s:00',
  1132.                 $this->regdate (array ($midyear$midmonth$midday)),
  1133.                 $midhour 10 '0' $midhour $midhour,
  1134.                 $midmin 10 '0' $midmin $midmin
  1135.             )
  1136.         );
  1137.  
  1138.         // 1852-10-15 이전이면 julian으로 변경
  1139.         if $this->is_gregorian ($midyear$midmonth$midday=== false {
  1140.             $r $this->gregorian2julian (array ($midyear$midmonth$midday));
  1141.             $midyear  $r->year;
  1142.             $midmonth $r->month;
  1143.             $midday   $r->day;
  1144.         }
  1145.  
  1146.         $j_ne $this->to_utc_julian (
  1147.             sprintf (
  1148.                 '%s %s:%s:00',
  1149.                 $this->regdate (array ($outgiyear$outgimonth$outgiday)),
  1150.                 $outgihour 10 '0' $outgihour $outgihour,
  1151.                 $outgimin 10 '0' $outgimin $outgimin
  1152.             )
  1153.         );
  1154.  
  1155.         // 1852-10-15 이전이면 julian으로 변경
  1156.         if $this->is_gregorian ($outgiyear$outgimonth$outgiday=== false {
  1157.             $r $this->gregorian2julian (array ($outgiyear$outgimonth$outgiday));
  1158.             $outgiyear  $r->year;
  1159.             $outgimonth $r->month;
  1160.             $outgiday   $r->day;
  1161.         }
  1162.  
  1163.         unset ($r);
  1164.         $r = (object) array (
  1165.             'center'  => (object) array (
  1166.                 'name'   => $this->month_st[$inginame],
  1167.                 'hname'  => $this->hmonth_st[$inginame],
  1168.                 'hyear'  => $this->human_year ($ingiyear),
  1169.                 'year'   => $ingiyear,
  1170.                 'month'  => $ingimonth,
  1171.                 'day'    => $ingiday,
  1172.                 'hour'   => $ingihour,
  1173.                 'min'    => $ingimin,
  1174.                 'julian' => $j_ce
  1175.             ),
  1176.             'ccenter' => (object) array (
  1177.                 'name'   => $this->month_st[$midname],
  1178.                 'hname'  => $this->hmonth_st[$midname],
  1179.                 'hyear'  => $this->human_year ($midyear),
  1180.                 'year'   => $midyear,
  1181.                 'month'  => $midmonth,
  1182.                 'day'    => $midday,
  1183.                 'hour'   => $midhour,
  1184.                 'min'    => $midmin,
  1185.                 'julian' => $j_cc
  1186.             ),
  1187.             'nenter'  => (object) array (
  1188.                 'name'   => $this->month_st[$outginame],
  1189.                 'hname'  => $this->hmonth_st[$outginame],
  1190.                 'hyear'  => $this->human_year ($outgiyear),
  1191.                 'year'   => $outgiyear,
  1192.                 'month'  => $outgimonth,
  1193.                 'day'    => $outgiday,
  1194.                 'hour'   => $outgihour,
  1195.                 'min'    => $outgimin,
  1196.                 'julian' => $j_ne
  1197.             )
  1198.         );
  1199.  
  1200.         # KASI-Lunar package 가 있으면, 천문과학연구원의 2004~2026년도 절기 데이터를
  1201.         # 이용한다.
  1202.         if class_exists ('oops\KASI\Lunar') ) {
  1203.             if $this->KASI == null )
  1204.                 $this->KASI new \oops\KASI\Lunar;
  1205.  
  1206.             # KASI-Lunar > 2.0.0 부터 사용 가능하다.
  1207.             # season method 가 없으면 진짜만세력 절기 데이터를 그냥 반환한다.
  1208.             if method_exists ($this->KASI'season') )
  1209.                 return $r;
  1210.  
  1211.             foreach $r as $k => $v {
  1212.                 # 2004-01 ~ 2026-12 이 후의 범위에서 Exception 이 발생하므로 예외 처리를 해 줘야 한다.
  1213.                 # KASI_Lunar 2.0.1 부터는 KASI_Lunar::is_exception = false; 설정으로 Exception 를
  1214.                 # 발생하지 않게 할 수 있다.
  1215.                 try {
  1216.                     $kv $this->KASI->season ($r->{$k}->name$r->{$k}->year);
  1217.                     if $kv != false {
  1218.                         $r->{$k}->month  $kv->month;
  1219.                         $r->{$k}->day    $kv->day;
  1220.                         $r->{$k}->hour   $kv->hour;
  1221.                         $r->{$k}->min    = $kv->min;
  1222.                         $r->{$k}->julian $this->to_utc_julian (
  1223.                             sprintf (
  1224.                                 '%s %s:%s:00',
  1225.                                 $this->regdate (array ($r->{$k}->year$r->{$k}->month$r->{$k}->day)),
  1226.                                 $r->{$k}->hour 10 '0' $r->{$k}->hour $r->{$k}->hour,
  1227.                                 $r->{$k}->min < 10 '0' $r->{$k}->min : $r->{$k}->min
  1228.                             )
  1229.                         );
  1230.                     }
  1231.                 catch \myException $e /* no action */ }
  1232.             }
  1233.         }
  1234.  
  1235.         return $r;
  1236.     }
  1237.     // }}}
  1238.  
  1239.     // {{{ +-- public (object) moonstatus ($v = null)
  1240.     /**
  1241.      * 양력일에 대한 음력월 합삭/망 데이터 구하기
  1242.      *
  1243.      * 예제:
  1244.      * {@example Lunar/tests/sample.php 311 56}
  1245.      *
  1246.      * @access public
  1247.      * @return stdClass    합삭/망 object
  1248.      *
  1249.      *    <pre>
  1250.      *    stdClass Object
  1251.      *    (
  1252.      *        [new] => stdClass Object      // 합삭 (New Moon) 데이터
  1253.      *            (
  1254.      *                [hyear] => AD 2013          // 합삭 AD/BC 형식 연도
  1255.      *                [year] => 2013              // 합삭 연도
  1256.      *                [month] => 7                // 합삭 월
  1257.      *                [day] => 8                  // 합삭 일
  1258.      *                [hour] => 16                // 합삭 시간
  1259.      *                [min] => 15                 // 합삭 분
  1260.      *                [julian] => 2456481.8020833 // Julian date (UTC)
  1261.      *            )
  1262.      *
  1263.      *        [full] => stdClass Object     // 망 (Full Moon) 데이터
  1264.      *            (
  1265.      *                [hyear] => AD 2013          // 망 AD/BC 형식 연도
  1266.      *                [year] => 2013              // 망 연도
  1267.      *                [month] => 7                // 망 월
  1268.      *                [day] => 23                 // 망 일
  1269.      *                [hour] => 2                 // 망 시간
  1270.      *                [min] => 59                 // 망 분
  1271.      *                [julian] => 2456496.2493056 // Julian date (UTC)
  1272.      *            )
  1273.      *    )
  1274.      *    </pre>
  1275.      *
  1276.      * @param int|string  날자형식
  1277.      *
  1278.      *    - unixstmap (1970년 12월 15일 이후부터 가능)
  1279.      *    - Ymd or Y-m-d
  1280.      *    - null data (현재 시간)
  1281.      *    - 1582년 10월 15일 이전의 날자는 율리우스력의 날자로 취급함.
  1282.      */
  1283.     public function moonstatus ($v null{
  1284.         list ($y$m$d$this->toargs ($v);
  1285.         list ($y$m$d$this->fix_calendar ($y$m$d);
  1286.  
  1287.         list (
  1288.             $y1$mo1$d1$h1$mi1,
  1289.             $ym$mom$dm$hm$mim,
  1290.             $y2$m2$d2$h2$mi2
  1291.         $this->getlunarfirst ($y$m$d);
  1292.  
  1293.         $j_new $this->to_utc_julian (
  1294.             sprintf (
  1295.                 '%s %s:%s:00',
  1296.                 $this->regdate (array ($y1$mo1$d1)),
  1297.                 $h1 10 '0' $h1 $h1,
  1298.                 $mi1 10 '0' $mi1 $mi1
  1299.             )
  1300.         );
  1301.  
  1302.         // 1852-10-15 이전이면 julian으로 변경
  1303.         if $this->is_gregorian ($y1$mo1$d1=== false {
  1304.             $r $this->gregorian2julian (array ($y1$mo1$d1));
  1305.             $y1 $r->year;
  1306.             $mo1 $r->month;
  1307.             $d1 $r->day;
  1308.         }
  1309.  
  1310.         $j_full $this->to_utc_julian (
  1311.             sprintf (
  1312.                 '%s %s:%s:00',
  1313.                 $this->regdate (array ($ym$mom$dm)),
  1314.                 $hm 10 '0' $hm $hm,
  1315.                 $mim 10 '0' $mim $mim
  1316.             )
  1317.         );
  1318.  
  1319.         // 1852-10-15 이전이면 julian으로 변경
  1320.         if $this->is_gregorian ($ym$mom$dm=== false {
  1321.             $r $this->gregorian2julian (array ($ym$mom$dm));
  1322.             $ym $r->year;
  1323.             $mom $r->month;
  1324.             $dm $r->day;
  1325.         }
  1326.  
  1327.         return (object) array (
  1328.             'new' => (object) array (
  1329.                 'hyear'  => $this->human_year ($y1),
  1330.                 'year'   => $y1,
  1331.                 'month'  => $mo1,
  1332.                 'day'    => $d1,
  1333.                 'hour'   => $h1,
  1334.                 'min'    => $mi1,
  1335.                 'julian' => $j_new
  1336.             ),   // 합삭 (New Moon)
  1337.             'full' => (object) array (
  1338.                 'hyear'  => $this->human_year ($ym),
  1339.                 'year'   => $ym,
  1340.                 'month'  => $mom,
  1341.                 'day'    => $dm,
  1342.                 'hour'   => $hm,
  1343.                 'min'    => $mim,
  1344.                 'julian' => $j_full
  1345.             )    // 망 (Full Moon)
  1346.         );
  1347.     }
  1348.     // }}}
  1349.  
  1350.     // {{{ +-- public (string) ganji_ref ($no, $mode = false)
  1351.     /**
  1352.      * dayfortune method의 ganji index 반환값을 이용하여, ganji
  1353.      * 값을 구함
  1354.      *
  1355.      * 예제:
  1356.      * {@example Lunar/tests/sample.php 163 56}
  1357.      *
  1358.      * @access public
  1359.      * @return string 
  1360.      * @param int ganji index number
  1361.      * @param bool 출력 모드 (false => 한글, true => 한자)
  1362.      */
  1363.     public function ganji_ref ($no$mode false{
  1364.         if $no 59 )
  1365.             $no -= 60;
  1366.  
  1367.         $m $mode 'hganji' 'ganji';
  1368.         return $this->{$m}[$no];
  1369.     }
  1370.     // }}}
  1371.  
  1372. }
  1373.  
  1374. /*
  1375.  * Local variables:
  1376.  * tab-width: 4
  1377.  * c-basic-offset: 4
  1378.  * End:
  1379.  * vim: set filetype=php noet sw=4 ts=4 fdm=marker:
  1380.  * vim600: noet sw=4 ts=4 fdm=marker
  1381.  * vim<600: noet sw=4 ts=4
  1382.  */
  1383. ?>

Documentation generated on Fri, 30 Aug 2024 06:10:50 +0900 by phpDocumentor 1.4.4