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

Source for file KASI_Lunar.php

Documentation is available at KASI_Lunar.php

  1. <?php
  2. /**
  3.  * Project: oops\KASI\Lunar:: 한국천문연구원 데이터를 기반으로 한 음/양력 변환 클래스<br>
  4.  * Files:   Lnuar.php<br>
  5.  * Dependency:
  6.  *   - {@link http://pear.oops.org/docs/li_myException.html oops/myException}
  7.  *   - {@link http://kr1.php.net/manual/en/book.calendar.php calendar extension}
  8.  *
  9.  * 이 패키지는 한국천문연구원의 음양력 데이터를 기반으로 하여 양력/음열간의 변환을
  10.  * 제공하며, aero님의 Date-Korean-0.0.2 perl module을 PHP로 포팅한 것이다.
  11.  *
  12.  * 양력 기준으로 1391-02-05 부터 2050-12-31 까지의 기간만 가능하며, 절기, 합삭/망
  13.  * 정보, 세차/월간/일진등의 정보는 oops\Lunar pear package를 이용하도록 한다.
  14.  *
  15.  * 이 패키지는 pear/Lunar package의 확장을 위하여 제작이 되었으며, 라이센스 문제로
  16.  * pear/Lunar package와 별도의 패키지로 제작이 되었다.
  17.  *
  18.  * @category    Calendar
  19.  * @package     oops\KASI\Lunar
  20.  * @author      JoungKyun.Kim <http://oops.org>
  21.  * @copyright   (c) 2018, OOPS.org
  22.  * @license     GPL (or Perl license)
  23.  * @link        http://pear.oops.org/package/Lnuar
  24.  * @since       File available since release 0.0.1
  25.  * @example     KASI-Lunar/tests/test.php Sample code
  26.  * @filesource
  27.  */
  28.  
  29. /**
  30.  * Namespace oops\KASI;
  31.  */
  32. namespace oops\KASI;
  33.  
  34. /**
  35.  * import myException class
  36.  */
  37. require_once 'myException.php';
  38. set_error_handler('myException::myErrorHandler');
  39.  
  40. /**
  41.  * import Lunar API
  42.  */
  43. require_once 'KASI_Lunar/Lunar_Tables.php';
  44.  
  45.  
  46. /**
  47.  * oops\KASI pear package의 main class
  48.  *
  49.  * 한국천문연구원 데이터를 기반으로 한 음/양력 변환 클래스
  50.  *
  51.  * 이 패키지는 한국천문연구원의 음양력 데이터를 기반으로 하여 양력/음열간의 변환을
  52.  * 제공하며, aero님의 Date-Korean-0.0.2 perl module을 PHP로 포팅한 것이다.
  53.  *
  54.  * 양력 기준으로 1391-02-05 부터 2050-12-31 까지의 기간만 가능하며, 절기, 합삭/망
  55.  * 정보, 세차/월간/일진등의 정보는 oops\Lunar pear package를 이용하도록 한다.
  56.  *
  57.  * 이 패키지는 pear/Lunar package의 확장을 위하여 제작이 되었으며, 라이센스 문제로
  58.  * pear/Lunar package와 별도의 패키지로 제작이 되었다. 물론 독립적으로 사용해도 무방
  59.  * 하다.
  60.  *
  61.  * @package     oops/KASI/Lunar
  62.  * @author      JoungKyun.Kim <http://oops.org>
  63.  * @copyright   (c) 2018, OOPS.org
  64.  * @license     GPL (or Perl license)
  65.  * @example     KASI-Lunar/tests/test.php Sample code
  66.  */
  67.  
  68. class Lunar {
  69.     // {{{ +-- public (object) tolunar ($v = null)
  70.     /**
  71.      * 양력 날자를 음력으로 변환
  72.      *
  73.      * 예제:
  74.      * {@example KASI-Lunar/tests/test.php 21 51}
  75.      *
  76.      * @access public
  77.      * @return stdClass    음력 날자 정보 반환
  78.      *
  79.      *    <pre>
  80.      *    stdClass Object
  81.      *    (
  82.      *        [fmt]    => 2013-06-09       // YYYY-MM-DD 형식의 음력 날자
  83.      *        [jd]     => 2456582          // 율리어스 적일
  84.      *        [year]   => 2013             // 연도
  85.      *        [month]  => 6                // 월
  86.      *        [day]    => 9                // 일
  87.      *        [leap]   =>                  // 음력 윤달 여부
  88.      *        [lmonth] => 1                // 평달/큰달 여부
  89.      *    )
  90.      *    </pre>
  91.      *
  92.      * @param int|string  날자형식
  93.      *    - unixstmap (1970년 12월 15일 이후부터 가능)
  94.      *    - Ymd or Y-m-d
  95.      *    - null data (현재 시간)
  96.      *    - 1582년 10월 15일 이전의 날자는 율리우스력의 날자로 취급함.
  97.      *      예.. 10월 14일은 그레고리력 10월 24일
  98.      */
  99.     public function tolunar ($v null{
  100.         list ($y$m$d$this->toargs ($v);
  101.  
  102.         $jd $this->cal2jd (array ($y$m$d));
  103.  
  104.         if $jd Tables::$MinDate || $jd Tables::$MaxDate {
  105.             throw new \myException (
  106.                 'Invalid date period. Valid period is from 1391-02-05 to 2050-12-31 with solar',
  107.                 E_USER_ERROR
  108.             );
  109.             return false;
  110.         }
  111.  
  112.         $day $jd Tables::$MinDate;
  113.  
  114.         $mon $this->bisect (Tables::$month$day);
  115.         $yer $this->bisect (Tables::$year$mon);
  116.  
  117.         $month $mon Tables::$year[$yer1;
  118.         $days  $day  Tables::$month[$mon1;
  119.  
  120.         // 큰달 작은달 체크
  121.         $lmoon Tables::$month[$mon+1Tables::$month[$mon];
  122.         $lmoon ($lmoon == 29false true;
  123.  
  124.         // 윤달 체크
  125.         $leap false;
  126.         if Tables::$leap[$yer!= && Tables::$leap[$yer<= $month {
  127.             if Tables::$leap[$yer== $month )
  128.                 $leap true;
  129.             $month -= 1;
  130.         }
  131.  
  132.         $year $yer Tables::$BaseYear;
  133.  
  134.         return (object) array (
  135.             'fmt'   => $this->datestring ($year$month$days'-'),
  136.             'jd'    => $jd,
  137.             'year'  => $year,
  138.             'month' => $month,
  139.             'day'   => $days,
  140.             'week'  => $this->jd2week ($jd),
  141.             'leap'  => $leap,
  142.             'lmoon' => $lmoon
  143.         );
  144.     }
  145.     // }}}
  146.  
  147.     // {{{ +-- public (object) tosolar ($v = null, $leap = false)
  148.     /**
  149.      * 음력 날자를 양력으로 변환.
  150.      *
  151.      * 예제:
  152.      * {@example KASI-Lunar/tests/test.php 21 51}
  153.      *
  154.      * @access public
  155.      * @return stdClass    양력 날자 정보 object 반환
  156.      *
  157.      *    <pre>
  158.      *    stdClass Object
  159.      *    (
  160.      *        [fmt]   => 2013-06-09       // YYYY-MM-DD 형식의 음력 날자
  161.      *        [jd]    => 2456527          // 율리어스 적일
  162.      *        [year]  => 2013             // 양력 연도
  163.      *        [month] => 7                // 월
  164.      *        [day]   => 16               // 일
  165.      *        [week]  => 6                // 요일
  166.      *    )
  167.      *    </pre>
  168.      *
  169.      * @param int|string날자형식
  170.      *
  171.      *    - unixstmap (1970년 12월 15일 이후부터 가능)
  172.      *    - Ymd or Y-m-d
  173.      *    - null data (현재 시간)
  174.      *
  175.      * @param bool 윤달여부
  176.      */
  177.     public function tosolar ($v null$leap false{
  178.         list ($y$m$d$this->toargs ($vtrue);
  179.  
  180.         $yer $y Tables::$BaseYear;
  181.  
  182.         // 윤달이 아닐 경우 값 보정
  183.         if $leap && (Tables::$leap[$yer1!= $m )
  184.              $leap false;
  185.  
  186.         $month Tables::$year[$yer$m 1;
  187.  
  188.         if $leap && ($m 1== Tables::$leap[$yer)
  189.             $month++;
  190.         else if Tables::$leap[$yer&& Tables::$leap[$yer<= $m )
  191.             $month++;
  192.  
  193.         $day Tables::$month[$month$d 1;
  194.         if $d || $day >= Tables::$month[$month+1{
  195.             throw new \myException ('Invalid day'E_USER_ERROR);
  196.             return false;
  197.         }
  198.  
  199.         $day += Tables::$MinDate;
  200.         $r $this->jd2cal ($day);
  201.  
  202.         return (object) array (
  203.             'fmt'   => $this->datestring ($r->year$r->month$r->day'-'),
  204.             'jd'    => $day,
  205.             'year'  => $r->year,
  206.             'month' => $r->month,
  207.             'day'   => $r->day,
  208.             'week'  => $r->week
  209.         );
  210.     }
  211.     // }}}
  212.  
  213.     // {{{ +-- public (int) cal2jd ($v)
  214.     /**
  215.      * 날자를 율리우스 적일로 변환
  216.      *
  217.      * @access public
  218.      * @return int 율리우스 적일(integer)
  219.      * @param array 연/월/일 배열 : array ($y, $m, $d)
  220.      */
  221.     public function cal2jd ($v{
  222.         if extension_loaded ('calendar') ) {
  223.             throw new \myException ('Don\'t support the calendar extension in PHP'E_USER_ERROR);
  224.             return false;
  225.         }
  226.  
  227.         list ($y$m$d$v;
  228.  
  229.         $julian false;
  230.  
  231.         $datestr $this->datestring ($y$m$d);
  232.         $julian false;
  233.         if $datestr 15821015 {
  234.             $julian true;
  235.             if $datestr 15821004 {
  236.                 $d += 10;
  237.                 $julian false;
  238.             }
  239.         }
  240.  
  241.         $old date_default_timezone_get ();
  242.         date_default_timezone_set ('UTC');
  243.  
  244.         $func $julian 'JulianToJD' 'GregorianToJD';
  245.         if $y )
  246.             $y--;
  247.         $r $func ((int) $m(int) $d(int) $y);
  248.  
  249.         date_default_timezone_set ($old);
  250.         return $r;
  251.     }
  252.     // }}}
  253.  
  254.     // {{{ +-- public (object) cal4jd ($jd = null)
  255.     /**
  256.      * 율리우스 적일을 율리우스력 또는 그레고리력으로 변환
  257.      *
  258.      * oops\KASI\Lunar::jd2cal 의 alias method로 deprecated
  259.      * 되었기 때문에 jd2cal method로 변경 해야 함.
  260.      *
  261.      * 1.0.2 부터 삭제 예정
  262.      *
  263.      * @access public
  264.      * @return stdClass    율리우스력 또는 그레고리력 정보
  265.      *
  266.      *    <pre>
  267.      *    stdClass Object
  268.      *    (
  269.      *        [year] => 2013              // 양력 연도
  270.      *        [month] => 7                // 월
  271.      *        [day] => 16                 // 일
  272.      *        [week] => 6                 // 요일
  273.      *    )
  274.      *    </pre>
  275.      *
  276.      * @param int 율리우스 적일. [default: 현재날의 적일]
  277.      * @deprecated deprecated since version 1.0.1
  278.      */
  279.     public function cal4jd ($jd null{
  280.         return $this->jd2cal ($jd);
  281.     }
  282.     // }}}
  283.  
  284.     // {{{ +-- public (object) jd2cal ($jd = null)
  285.     /**
  286.      * 율리우스 적일을 율리우스력 또는 그레고리력으로 변환
  287.      *
  288.      * @access public
  289.      * @return stdClass    율리우스력 또는 그레고리력 정보
  290.      *
  291.      *    <pre>
  292.      *    stdClass Object
  293.      *    (
  294.      *        [year] => 2013              // 양력 연도
  295.      *        [month] => 7                // 월
  296.      *        [day] => 16                 // 일
  297.      *        [week] => 6                 // 요일
  298.      *    )
  299.      *    </pre>
  300.      *
  301.      * @param int 율리우스 적일. [default: 현재날의 적일]
  302.      */
  303.     public function jd2cal ($jd null{
  304.         if extension_loaded ('calendar') ) {
  305.             throw new \myException ('Don\'t support the calendar extension in PHP'E_USER_ERROR);
  306.             return false;
  307.         }
  308.  
  309.         if $jd )
  310.             $jd unixtojd (time ());
  311.  
  312.         $cvt ($jd 2299160CAL_GREGORIAN CAL_JULIAN;
  313.         $r = (object) cal_from_jd ($jd$cvt);
  314.         if $r->year )
  315.             $r->year++;
  316.  
  317.         return (object) array (
  318.             'year'  => $r->year,
  319.             'month' => $r->month,
  320.             'day'   => $r->day,
  321.             'week'  => $r->dow
  322.         );
  323.     }
  324.     // }}}
  325.  
  326.     // {{{ +-- public (int) jd2week ($jd = null)
  327.     /**
  328.      * 율리우스 적일로 요일 정보를 구함
  329.      *
  330.      * @access public
  331.      * @return int         요일 배열 인덱스
  332.      *
  333.      *  0(일) ~ 6(토)
  334.      *
  335.      * @param int 율리우스 적일. [default: 현재날의 적일]
  336.      */
  337.     public function jd2week ($jd null{
  338.         if $jd {
  339.             $today date ('Y-m-d'time ());
  340.             $t preg_split ('/-/'$today);
  341.             $jd $this->cal2jd ($t);
  342.         }
  343.  
  344.         return fmod ($jd 17);
  345.         /*
  346.         $mjd = $jd - 2400000.5;
  347.         $widx = $mjd % 7 + 3;
  348.         if ( $widx < 3 )
  349.             $widx += 7;
  350.  
  351.         if ( $widx > 6 )
  352.             $widx -= 7;
  353.  
  354.         return $widx;
  355.          */
  356.     }
  357.     // }}}
  358.  
  359.     // {{{ +-- private (array) toargs ($v, $lanur = false)
  360.     /**
  361.      * 입력된 날자 형식을 연/월/일의 멤버를 가지는 배열로 반환한다.
  362.      * 입력된 변수 값은 YYYY-MM-DD 형식으로 변환 된다.
  363.      *
  364.      * 예제:
  365.      * {@example Lunar/tests/sample.php 30 25}
  366.      *
  367.      * @access public
  368.      * @return array 
  369.      *    <pre>
  370.      *        Array
  371.      *        (
  372.      *            [0] => 2013
  373.      *            [1] => 7
  374.      *            [2] => 16
  375.      *        )
  376.      *    </pre>
  377.      * @param string|int날자형식
  378.      *
  379.      *    - unixstmap (1970년 12월 15일 이후부터 가능)
  380.      *    - Ymd or Y-m-d
  381.      *    - null data (현재 시간)
  382.      */
  383.     private function toargs (&$v$lunar false{
  384.         if $v == null {
  385.             $y = (int) date ('Y');
  386.             $m = (int) date ('m');
  387.             $d = (int) date ('d');
  388.         else {
  389.             if $lunar {
  390.  
  391.             }
  392.  
  393.             if is_numeric ($v&& $v 30000000 {
  394.                 // unit stamp ?
  395.                 $y = (int) date ('Y'$v);
  396.                 $m = (int) date ('m'$v);
  397.                 $d = (int) date ('d'$v);
  398.             else {
  399.                 if preg_match ('/^(-?[0-9]{1,4})[\/-]?([0-9]{1,2})[\/-]?([0-9]{1,2})$/'trim ($v)$match) ) {
  400.                     array_shift ($match);
  401.                     list ($y$m$d$match;
  402.                 else {
  403.                     throw new \myException ('Invalid Date Format'E_USER_WARNING);
  404.                     return false;
  405.                 }
  406.             }
  407.  
  408.             if $lunar && $y 1969 && $y 2038 {
  409.                 $fixed mktime (000$m$d$y);
  410.                 $y = (int) date ('Y'$fixed);
  411.                 $m = (int) date ('m'$fixed);
  412.                 $d = (int) date ('d'$fixed);
  413.             else {
  414.                 if $m 12 || $d 31 {
  415.                     throw new \myException ('Invalid Date Format'E_USER_WARNING);
  416.                     return false;
  417.                 }
  418.             }
  419.         }
  420.         $v $this->datestring ($y$m$d'-');
  421.  
  422.         return array ($y$m$d);
  423.     }
  424.     // }}}
  425.  
  426.     // {{{ +-- private bisect ($a, $x)
  427.     private function bisect ($a$x{
  428.         $lo 0;
  429.         $hi count ($a);
  430.  
  431.         while $lo $hi {
  432.             $mid = (int) (($lo $hi2);
  433.             if $x $a[$mid)
  434.                 $hi $mid;
  435.             else
  436.                 $lo $mid 1;
  437.         }
  438.  
  439.         return --$lo;
  440.     }
  441.     // }}}
  442.  
  443.     // {{{ +-- private datestring ($y, $m, $d)
  444.     private function datestring ($y$m$d$dash ''{
  445.         if $m 10 )
  446.             $m '0' . (int) $m;
  447.         if $d 10 )
  448.             $d '0' . (int) $d;
  449.  
  450.         return $y $dash $m $dash $d;
  451.     }
  452.     // }}}
  453. }
  454. ?>

Documentation generated on Tue, 14 May 2019 02:00:09 +0900 by phpDocumentor 1.4.4