<!--// XE ver.1.2.x 게시판을 이용한 플래너/음력달력  (Skin Planner123-Standard)-----------------------
## [author]
##  - Keysung Chung, 2009, 07, 28
##  - http://chungfamily.woweb.net/
## [function]
##  - 24절기 일자를 구하기 위해 Chilbong Kim님의 class.calendar.php와 class.solar.php를 사용
##  - 기타 펑션은 인터넷에서 구하거나 직접 코딩함.
## [changes]
##  - PlannerXE123 ver. 1.7.0 : Keysung Chung, 2010, 08, 01
##  - PlannerXE123 ver. 1.6.0 : Keysung Chung, 2010, 07, 01
##  - PlannerXE123 ver. 1.5.0 : Keysung Chung, 2010, 06, 15
##  - PlannerXE123 ver. 1.4.0 : Keysung Chung, 2010, 06, 01
##  - PlannerXE123 ver. 1.3.0 : Keysung Chung, 2010, 05, 15
##  - PlannerXE123 ver. 1.2.0 : Keysung Chung, 2010, 05, 01
##  - PlannerXE123 ver. 1.1.0 : Keysung Chung, 2010, 04, 14
##  - PlannerXE123 ver. 1.0.0 : Keysung Chung, 2010, 04, 01
##  - PlannerXE123 ver. 0.3 : Keysung Chung, 2010, 02, 28
##  - PlannerXE123 ver. 0.2 : Keysung Chung, 2009, 11, 09
##  - PlannerXE123 ver. 0.1 : Keysung Chung, 2009, 07, 28
----------------------------------------------------------------------- -->
{@ $var_version = "PlannerXE123: Skin Ver 1.7.0"}
<?php
$GLOBALS['pOption'] = Context::get('pOption');  // XE변수 넘겨받기 위해서.
$pOption=$GLOBALS['pOption'];                   // XE변수 넘겨받기 위해서.
$GLOBALS['pYear'] = Context::get('pYear');  // XE변수 넘겨받기 위해서.
$pYear=$GLOBALS['pYear'];                   // XE변수 넘겨받기 위해서.
$GLOBALS['pMonth'] = Context::get('pMonth');    // XE변수 넘겨받기 위해서.
$pMonth=$GLOBALS['pMonth'];                     // XE변수 넘겨받기 위해서.
?>

{@ $link_path = getUrl('','mid',$mid,'dummy',1,'offset',$offset)}
{@ $XE_path = getUrl('')}

{@ $today_bgcolor="#CDE6AC"}   <!--// 달력의 당일 칸 배경색 -->
{@ $today_bodercolor="#58792E"}   <!--// 달력의 당일 칸 border 색 -->
{@ $mouseover_bgcolor="#ddfffa"}   <!--// 달력의 칸에 마우스오버시 배경색 -->

<!--@if($module_info->calendar_bgcolor == null )-->
	{@ $day_bgcolor="white"}      <!--// 달력의 평일 칸 배경색 -->
<!--@else-->
	{@ $day_bgcolor=$module_info->calendar_bgcolor}      <!--// 달력의 평일 칸 배경색 -->
<!--@end-->

<!--//  CSS 인쿨르드 -->
<!--%import("./css/planner123_calendar.css")-->

<?php
$linkpath = $__Context->link_path;
$xepath = $__Context->XE_path;
$skinpath = $tpl_path; // 스킨 설치 경로지정
//echo $linkpath;
//echo $skinpath;
?>

<!--//  Class 함수 인쿨르드 시작 -->
<?php
//require_once 'class.calendar.php';
//require_once 'class.solar.php';
//require_once 'class.lunar.php';
//include 'function_calendar_month.php';
?>
<!--//  인쿨르드가 작동이 안되어 부득이 평션 소스 전체를 복사해서 넣음 -->

<!--//  class.calendar.php 소스 -->
<?php
##
## this file name is 'class.calendar.php'
##
## calendar123 object
##
## [author]
##  - Chilbong Kim, <san2(at)linuxchannel.net>
##  - http://linuxchannel.net/
##
## [changes]
##  - 2009.06.08: some
##  - 2007.07.28 : support win32 PHP4(on Microsoft Windows) and Unix
##  - 2005.04.12 : new build
##
## [valid date]
##  - unix timestamp base: 1902-01-01 00:00:00 <= date <= 2037-12-31 23:59:59 (guess)
##  - JD(Julian Day) base: BC 4713-01-01 12:00 GMT <= Gregorian date <= AD 9999 (guess)
##
## [download & online source view]
##  - http://ftp.linuxchannel.net/devel/php_calendar/
##
## [demo]
##  - http://linuxchannel.net/gaggle/calendar.php
##
## [references]
##  - http://www.linuxchannel.net/docs/solar-24terms.txt
##  - http://www.linuxchannel.net/docs/lunar.txt
##  - http://ftp.linuxchannel.net/devel/php_solar/
##  - http://ftp.linuxchannel.net/devel/php_lunar/
##  - http://www.merlyn.demon.co.uk/ // Astronomy and Astronautics
##  - http://www.boogle.com/info/cal-overview.html
##
## [unit and format]
##  - date(ZONE) <-> JD(TT) : calcurated that date to JD(+64), JD to date(-64)
##  - utime(ZONE) <-> JD(TT): calcurated that utime to JD(-64), JD to utime(+64)
##  - date(ZONE) <-> utime(ZONE) : none
##  * ZONE is local system time zone, such as KST, GMT
##  * KST - 9H = GMT, GMT + 12H = UT, UT - delta T = TT
##  * JD(TT) is adapted delta 'T(J2000.0 is -64)' from UT(= GMT + 12H)
##
## [compare 1. PHP4(win32) internal functions VS this method(object)]
##  - time()            -
##  - date()            _date()        // private, base on unix timestamp, BC 4313 ~ AD 9999(guess)
##  - mktime()            _mktime()    // private, support native value, BC 4313 ~ AD 9999(guess)
##
## [compare 2. PHP4(win32) calendar module VS this method(object)]
##  - gregoriantojd()        mkjd()        // public, support hour, minute, seconds, BC 4313 ~ AD 9999(guess)
##  - jdtogregorian()        date()        // public, same above, but same as `date()'
##  - jddayofweek()        jddayofweek    // public, similar
##  - cal_days_in_month()    days_in_month()    // public, similar
##  - unixtojd()        _utime2jd()    // private, same above
##  - jdtounix()        _jd2utime()    // private, same above
##
## [usage] -- see that last row of this source
##  $jd = calendar123::mkjd(23,59,59,12,31,1901);
##  echo calendar123::date('Y-m-d H:i:s T',$jd);
##

class calendar123
{
  ## private, get Julian day -- same as gregoriantojd()
  ##
  ## http://en.wikipedia.org/wiki/Julian_day
  ## http://ko.wikipedia.org/wiki/%EC%9C%A8%EB%A6%AC%EC%9A%B0%EC%8A%A4%EC%9D%BC
  ## ftp://ssd.jpl.nasa.gov/pub/eph/export/C-versions/hoffman/
  ## http://blog.jidolstar.com/482
  ##
  ## Julian date
  ## JD 0.0 => BC 4713-01-01 12:00 GMT <= BC 4713-01-01 21:00 KST
  ##
  function &_getjd($Y, $M=1, $D=1, $H=21, $I=0, $S=0, $tojulian=FALSE)
  {
    $H -= date('Z')/3600; // local zone to GMT

    if(func_num_args() < 3) // Y is unix_timestamp
    { list($Y,$M,$D,$H,$I,$S) = explode(' ',calendar123::_date('Y n j G i s',$Y-date('Z'))); }

    if($M < 3) { $M += 12; $Y--; }

    $S += 64; // is J2000.0 delta 'T', patch san2@2007.07.28
    $D += ($H/24.0) + ($I/1440.0) + ($S/86400.0);
    $A = floor($Y/100.0);
    $B = $tojulian ? 0 : (2.0 - $A + floor($A/4.0));  // juliantojd() $B = 0

    $JD= sprintf('%.13f',floor(365.25*($Y+4716.0))+floor(30.6001*($M+1.0))+$D+$B-1524.5);
    $D = sprintf('%.13f',$JD-2451545.0); // float, number of days
    $J = sprintf('%.4f',2000.0+($D/365.25)); // // Jxxxx.xxxx format
    $T = sprintf('%.13f',$D/36525.0); // // Julian century

    return array($JD,$J,$D,$T);
  }

  ## private, get date(gregorian) from JD -- same as jdtogregorian()
  ##
  ## JD to `YYYY MM DD HH II SS', JD is UT
  ##
  function &_todate($JD)
  {
    // JD >= 2299160.5 gregorian
    $JD += date('Z')/86400; // JD to local zone(JD)
    $JD -= 64/86400; // is J2000.0 delta 'T', patch san2@2007.07.28

    $Z = $JD + 0.5; // float
    $W = (int)(($Z-1867216.25) / 36524.25);
    $X = (int)($W / 4);
    $A = (int)($Z + 1 + $W - $X);
    $B = (int)($A + 1524);
    $C = (int)(($B-122.1) / 365.25);
    $D = (int)(365.25 * $C); // is not $D = ($B - 122.1)
    $E = (int)(($B-$D) / 30.6001);
    $F = (int)(30.6001 * $E); // is not $F = ($B -$D)

    $_d = $B - $D - $F;
    $_m = $E - 1;
    $_y = $C - 4716;

    $JD -= 0.5; // UT to GMT -12.0H
    $JD = ($JD - (int)$JD) * 24.0;
    $_h = (int)$JD;
    $JD = ($JD - $_h) * 60.0;
    $_i = (int)$JD;
    $JD = ($JD - $_i) * 60.0;
    $_s = round($JD);

    if($_s > 59) { $_s -= 60; $_i++; }
    else if($_s < 0) { $_s += 60; $_i--; }

    if($_i > 59) { $_i -= 60; $_h++; }
    else if($_i < 0) { $_i += 60; $_h--; }

    if($_h > 23) { $_h -= 24; $_d++; }
    else if($_h < 0) { $_h +=24; $_d--; }

    if($_m > 12) { $_m -= 12; $_y++; }
    else if($_m < 0) { $_m +=12; $_y--; }

    return array($_y,$_m,$_d,$_h,$_i,$_s);
  }

  ## private, get JD(julian day) from unix timestamp -- same as unixtojd()
  ##
  ## D -- get the number of days from base JD
  ## D = JD(Julian Day) - 2451545.0, base JD(J2000.0)
  ##
  ## base position (J2000.0), 2000-01-01 12:00:00 GMT
  ## as   mktime(12,0,0-64,1,1,2000) == 946695536 unix timestamp at KST, -64 is delta 'T'
  ## as gmmktime(12,0,0-64,1,1,2000) == 946727936 unix timestamp at GMT, -64 is delta 'T'
  ##
  ## valid JD: 1902-01-01 00:00:00 ZONE <= JD <= 2037-12-31 23:59:59 ZONE
  ##
  function &_utime2jd($utime)
  {
    $D = $utime - 946727936; // number of time
    $D = sprintf('%.13f',$D/86400); // float, number of days
    $JD= sprintf('%.13f',$D+2451545.0); // float, Julian Day
    //$J = sprintf('%.4f',2000.0+($D/365.25)); // Jxxxx.xxxx format
    //$T = sprintf('%.13f',$D/36525.0); // Julian century

    return $JD; // float
  }

  ## private, get unix timestamp from JD -- same as jdtounix()
  ##
  ## 1970-01-01 12:00:00 GMT = 2440587.6257407409139 JD = J1970.0
  ## valid JD: 1902-01-01 00:00:00 ZONE <= JD <= 2037-12-31 23:59:59 ZONE
  ##
  function &_jd2utime($JD)
  {
    $JD -= 2440587.6257407409139; // convert to base JD(J1970.0), J2000.0 delta 'T', but it's not need

    $seconds = round($JD*86400); // convert to time seconds base on 1970-01-01 00:00:00
    $seconds += 43200; // to GMT -12H(43200 seconds)
    $seconds -= date('Z'); // to local time zone

     return $seconds;
  }

  ## private, check datetime that it's null or not null
  ##
  function &__check_datetime($argc, &$Y, &$M, &$D, &$H, &$I, &$S)
  {
    if($argc >= 6) return TRUE;

    list($Y,$_M,$_D,$_H,$_I,$_S) = explode(' ',date('Y n j G i s',time()));
    if($argc < 5) $D = $_D;
    if($argc < 4) $M = $_M;
    if($argc < 3) $S = $_S;
    if($argc < 2) $I = $_I;
    if($argc < 1) $H = $_H;
  }

  ## public, make JD -- match to mktime()
  ##
  ## Julian date
  ## J0.0 = BC 4713-01-01 12:00 GMT = BC 4713-01-01 21:00 KST ~ AD 9999
  ##
  function &mkjd($H=21, $I=0, $S=0, $M=1, $D=1, $Y=NULL)
  {
    calendar123::__check_datetime(func_num_args(),&$Y,&$M,&$D,&$H,&$I,&$S);

    list($JD) = calendar123::_getjd($Y,$M,$D,$H,(int)$I,(int)$S);

    return $JD; // folat, JD is UT base
  }

  ## private, get unix timestamp from date -- same as mktime()
  ##
  ## valid date: 1902-01-01 00:00:00 ZONE <= date <= 2037-12-31 23:59:59 ZONE
  ##
  function &_mktime($H=9, $I=0, $S=0, $M=1, $D=1, $Y=NULL)
  {
    if($Y>1970 && $Y<2038) return mktime($H,$I,$S,$M,$D,$Y);

    calendar123::__check_datetime(func_num_args(),&$Y,&$M,&$D,&$H,&$I,&$S);

    $JD = calendar123::mkjd($H,$I,$S,$M,$D,$Y);
    $utime = calendar123::_jd2utime($JD);

     return $utime;
  }

  ## private,  same as `date()' function, base on unix timestamp(support Microsoft Windows PHP4)
  ##
  ## valid date: 1902-01-01 00:00:00 ZONE <= date <= 2037-12-31 23:59:59 ZONE
  ##
  function &_date($format, $utime=NULL)
  {
    if($utime === NULL) $utime = time();
    if($utime>=0 && $utime<2145884400) return date($format,$utime);

    $JD = calendar123::_utime2jd($utime);
    $str = calendar123::date($format,$JD);

     return $str;
  }

  ## public, same as `date()' function, but base on JD by UT(delta T)
  ##
  ## valid JD: BC 4713-01-01 12:00 GMT ~ AD 9999
  ##
  function &date($format, $JD=NULL)
  {
    static $_weeks = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
    static $_months = array('January','February','March','April','May','June','July','August',
        'September','Octorber','November','December');
    static $_ordinals = array(1=>'st',21=>'st',31=>'st',2=>'nd',22=>'nd',3=>'rd',23=>'rd');

    if(func_num_args()<2 || $JD==NULL) $JD = calendar123::mkjd(); // current JD(UT)
    if(!$format || is_array($format)) return calendar123::_todate($JD); // array

    list($Y,$M,$D,$H,$I,$S) = calendar123::_todate($JD);

    $_Y = sprintf('%04d',$Y);
    $_M = sprintf('%02d',$M);
    $_D = sprintf('%02d',$D);
    $_H = sprintf('%02d',$H);
    $_I = sprintf('%02d',$I);
    $_S = sprintf('%02d',$S);
    $_Z = date('Z');
    $_W = calendar123::jddayofweek($JD + ($_Z/86400)); // JD apply to local TimeZone
    $_O = date('O'); // example +0900
    $_R = substr($_weeks[$_W],0,3).", $_D ".substr($_months[$M-1],0,3)." $H:$I:$S $_O";
    $_C = "${_Y}-${_M}-${_D}T${_H}:${_I}:${_S}".$_O{0}.$_O{1}.$_O{2}.':'.$_O{3}.$_O{4};

    $l = strlen($format);
    for($i=0; $i<$l; $i++)
    {
        $char = $format[$i];
        switch($char)
        {
            case 'a': $r .= ($H<12) ? 'am' : 'pm'; break;
            case 'A': $r .= ($H<12) ? 'AM' : 'PM'; break;
            case 'B': $r .= calendar123::itime($H,$I,$S); break;
            case 'c': $r .= $_C; break; // ISO 8601 date (added in PHP5)
            case 'd': $r .= $_D; break;
            case 'D': $r .= substr($_weeks[$_W],0,3); break;
            case 'F': $r .= $_months[$M-1]; break;
            case 'g': $r .= (($H-1) % 12) + 1; break;
            case 'G': $r .= $H; break;
            case 'h': $r .= sprintf('%02d',(($H-1)%12)+1); break;
            case 'H': $r .= $_H; break;
            case 'i': $r .= $_I; break;
            //case 'I': $r .= 0; break;
            case 'j': $r .= $D; break;
            case 'l': $r .= $_weeks[$_W]; break;
            case 'L': $r .= calendar123::isleap($Y); break;
            case 'm': $r .= $_M; break;
            case 'M': $r .= substr($_months[$M-1],0,3); break;
            case 'n': $r .= $M; break;
            case 'O': $r .= date('O'); break;
            case 'r': $r .= $_R; break;
            case 's': $r .= $_S; break;
            case 'S': $r .= $_ordinals[$D] ? $_ordinals[$D] : 'th'; break;
            case 't': $r .= calendar123::days_in_month($Y,$M); break;
            case 'T': $r .= date('T'); break;
            case 'U': $r .= time(); break;
            case 'w': $r .= $_W; break; // JD to local zone
            case 'W': $r .= calendar123::weeknumber($Y,$M,$D); break; // ISO-8601
            case 'y': $r .= substr($_Y,-2); break;
            case 'Y': $r .= $Y; break;
            case 'z': $r .= calendar123::dayofyear($Y,$M,$D); break;
            case 'Z': $r .= $_Z; break; // KST zone +9H, in seconds

            default : $r .= $char; break;
        }
    }

    return $r; // string
  }

  ## public, get leap year
  ##
  ## #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
  ##
  ## +-- 4*Y ! // normal
  ## `-- 4*Y
  ##      |-- 100*Y ! // leap
  ##      `-- 100*Y
  ##           |-- 400*Y ! // normal
  ##           `-- 400*Y   // leap
  ##
  ## but, 4000*Y is not normal year, is leap year
  ## http://user.chollian.net/~kimdbin/re/leap_year.html
  ##
  function &isleap($year)
  {
    if($year%4) return FALSE;
    else if($year%100) return TRUE;
    else if($year%400) return FALSE;

    return TRUE; // else 400*Y
  }

  ## public, get week idx
  ##
  ## 0(sun), 1(mon), 2(tue), 3(wed), 4(thu), 5(fri), 6(sat)
  ##
  function &jddayofweek($JD)
  {
    return floor($JD+1.5)%7; // integer
  }

  function &dayofyear($Y, $M, $D)
  {
    list($JDE) = calendar123::_getjd($Y,$M,$D);
    list($JDS) = calendar123::_getjd($Y,1,1);

    return (int)($JDE - $JDS);
  }

  ## ISO-8601, start on Thurday
  ##
  function &weeknumber($Y, $M, $D)
  {
    list($JD) = calendar123::_getjd($Y,1,1);

    $widx = calendar123::jddayofweek($JD) - 1;
    $days = calendar123::dayofyear($Y,$M,$D);

    $midx = ($widx<0) ? 6 : $widx;
    $days = ($midx<4) ? ($days+$midx) : ($days+$midx-7);
    $n = floor($days/7) + 1;

    if($n == 0)
    {
        list($JD) = calendar123::_getjd($Y-1,1,1);
        $widx = calendar123::jddayofweek($JD);
        $n = ($widx>4) ? 52 : 53;
    }

    return $n; // integer
  }

  ## public, get swatch internet time, base BMT = GMT + 1
  ## same as date('B')
  ##
  function &itime($H, $I, $S)
  {
    $B = ($H-(date('Z')/3600)+1)*41.666 + $I*0.6944 + $S*0.01157;
    $B = ($B>0) ? $B : $B+1000.0;

    return sprintf('%03d',$B);
  }

  /***
  function &days_in_month($year, $month, $JDS=0)
  {
    list($JDS) = calendar123::_getjd($year,$month,1);
    list($JDE) = calendar123::_getjd($year,$month+1,1);

    $term = (int)($JDE - $JDS);

    return $term; // integer
  }
  ***/

  ## public
  ##
  function &days_in_month($year, $month)
  {
    static $months = array(31,0,31,30,31,30,31,31,30,31,30,31);

    $n = $months[$month-1];
    $n = $n ? $n : (calendar123::isleap($year) ? 29 : 28);

    return $n; // integer
  }

  ## public
  ##
  function &month_info($year, $month)
  {
    if($year<1902 || $year>2037)
    {
        list($JD) = calendar123::_getjd($year,$month,1);
        $term = calendar123::days_in_month($year,$month);
        $week = calendar123::jddayofweek($JD); // week idx
        $minfo = array($week,$term);
    } else
    {
        $utime = mktime(23,59,59,$month,1,$year);
        $minfo = explode(' ',date('w t',$utime));
    }

    return $minfo; // array($week,$term)
  }

  /***
  function &_calendar($year, $month)
  {
    list($week,$term) = calendar123::month_info($year,$month);

    $eidx = 3;
    $sat = 7 - $week;
    $chk = $sat + 28;
    $sats = array($sat,$sat+7,$sat+14,$sat+21);
    $suns = array($sat-6,$sat+1,$sat+8,$sat+15);
    $refs = range(1,$term);

    if($chk <= $term)
    {
        $eidx++;
        $sats[] = $chk;
        $suns[] = $sat + 22;
    }

    ## check last sunday
    ##
    if($term-$sats[$eidx] > 0)
    {
        $sats[] = $sats[$eidx] + 7;
        $suns[] = $sats[$eidx] + 1;
        $eidx++;
    }

    ## rewrite array
    ##
    for($i=0; $i<=$eidx; $i++)
    {
        for($j=$suns[$i]; $j<=$sats[$i]; $j++) $r[$i][] = &$refs[$j-1];
    }

    //ksort($r);

    echo "$week;$term\n";
    print_r($suns);
    print_r($sats);
    print_r($r);
  }
  ***/

  ## public
  ##
  function &calendar($year, $month)
  {
    list($week,$term) = calendar123::month_info($year,$month);

    $eidx = 3;
    $refs = range(1,$term); // reference of days
    $fsat = 7 - $week; // first Saturday

    ## make index array such as (Sun,Sat)
    ##
    for($i=0; $i<=3; $i++)
    {
        $isat = $fsat + ($i*7); // index of Saturday
        $idxs[] = array($isat-6,$isat);
    }

    ## check last Saturday and Sunday
    ##
    if(($fsat+28) <= $term) $idxs[++$eidx] = array($fsat+22,$fsat+28);
    if(($term-$idxs[$eidx][1]) > 0)
    {
        $idxs[] = array($idxs[$eidx][0]+7,$idxs[$eidx][1]+7);
        $eidx++;
    }

    ## rewrite days
    ##
    for($i=0; $i<=$eidx; $i++)
    {
        for($j=$idxs[$i][0]; $j<=$idxs[$i][1]; $j++) $r[$i][] = &$refs[$j-1];
    }

    return $r; // array
  }
} // end of class

/**** example *********
$_y = 2040;
$_m = 12;
$r = calendar123::calendar($_y,$_m);

echo '<PRE>';
echo "      $_m $_y\n";
echo "Su Mo Tu We Th Fr Sa\n";

$size = sizeof($r);
for($i=0; $i<$size; $i++)
{
  printf("%2s",$r[$i][0]);
  for($j=1; $j<7; $j++) printf("%3s",$r[$i][$j]);
  echo "\n";
}
print_r($r);
**********************/
?>

<!--//  인쿨르드가 작동이 안되어 부득이 평션 소스 전체를 복사해서 넣음 -->
<!--//  class.solar.php 소스 -->
<?php
##
## this file name is 'class.solar.php'
##
## solar object -- get sun position or 24 solar terms
##
## [author]
##  - Chilbong Kim, <san2(at)linuxchannel.net>
##  - http://linuxchannel.net/
##
## [changes]
##  - 2009.06.08 : extended, date() to calendar123::_date() of class.caledar.php
##  - 2005.04.17 : add sunrise_sunset()
##  - 2005.02.06 : rebuid deg2valid(), add zodiac()
##  - 2005.01.24 : rebuild time2stime(), atan2()
##  - 2005.01.18 : bug fixed:$RA
##  - 2003.09.08 : bug fixed
##  - 2003.09.06 : new build
##
## [근사식에 대한 신뢰]
##  - 표준편차 : 1289.7736 = 21.5 minutes (standard deviation)
##  - 평균오차 : 817.57409541246 = 13.6 minutes
##  - 최대오차 : +4102.7340(68.4 minutes), -4347.2395(72.5 minutes)
##
## [근사식으로 계산한 24절기 실제 오차] 1902 ~ 2037 년
##  - 표준편차 : 1122.1921 = 18.7 분
##  - 평균오차 : +686.08382175161 = +11.4 분
##  - 최대오차 : +4297.252300024 = +71.6 분, -4278.048699975 = -71.3 분
##  - 최소오차 : +0.16999998688698 = 0 초
##
## [근사식 + 년도 보정으로 계산한 24절기 실제 오차] 1902 ~ 2037 년
##  - 표준편차 : 450.8534 = 7.5 분
##  - 평균오차 : +305.38638890903 = 5.0 분
##  - 최대오차 : +3028.2343000174 = +50.5 분, -1982.9391000271 = -33.1 분
##  - 최소오차 : +0.0085000991821289 = 0 초
##
## [valid date]
##  - 1902.01.01 00:00:00 <= utime <= 2037.12.31 23:59:59
##
## [support date]
##  - unix timestamp base: 1902-01-01 00:00:00 <= date <= 2037-12-31 23:59:59 (guess)
##  - JD(Julian Day) base: BC 4713-01-01 12:00 GMT <= Gregorian date <= AD 9999 (guess)
##
## [download & online source view]
##  - http://ftp.linuxchannel.net/devel/php_solar/
##  - http://ftp.linuxchannel.net/devel/php_calendar/
##
## [demo]
##  - http://linuxchannel.net/gaggle/solar.php
##
## [docs]
##  - http://linuxchannel.net/docs/solar-24terms.txt
##
## [references]
##  - http://cgi.chollian.net/~kohyc/
##  - http://user.chollian.net/~kimdbin/
##  - http://user.chollian.net/~kimdbin/re/calendar.html
##  - http://user.chollian.net/~kimdbin/re/suncoord.html
##  - http://user.chollian.net/~kimdbin/qna/al138.html
##  - http://ruby.kisti.re.kr/~manse/contents-3.html
##  - http://ruby.kisti.re.kr/~anastro/sub_index.htm
##  - http://www-ph.postech.ac.kr/~obs/lecture/lec1/elementary/nakedeyb.htm
##  - http://ruby.kisti.re.kr/~anastro/calendar/etime/ETime.html
##  - http://www.sundu.co.kr/5-information/5-3/5f3-3-5-04earth-1.htm
##  - http://www-ph.postech.ac.kr/~obs/lecture/lec1/elementary/nakedeya.htm
##  - http://upgradename.com/calm.php
##  - http://aa.usno.navy.mil/faq/docs/SunApprox.html
##  - http://aa.usno.navy.mil/data/docs/JulianDate.html
##
## [usage]
##
## [example]
##  require_once 'class.calendar.php';
##  require_once 'class.solar.php';
##  $sun = array();
##  $terms = solar::terms(date('Y'),1,12,&$sun);
##  print_r($terms);
##  print_r($sun);
##  print_r(solar::sun(time()));
##

class solar
{
  ## check solar terms in today or tomorrow
  ##
  function &solar($utime=0, $GMT=FALSE)
  {
    return solar::today($utime,$GMT);
  }

  function &today($utime=0, $GMT=FALSE)
  {
    if($utime == '') $utime = time();
    if($GMT) $utime -= 32400;

    list($year,$moon,$moonday) = explode(' ',date('Y n nd',$utime));

    $terms = solar::terms($year,$moon,0);

    if($term = $terms[$moonday])
    {
        $str = '오늘은 <B>'.$term.'</B>입니다.';
    }
    else if($term = $terms[date('nd',$utime+86400)])
    {
        $str = '내일은 <B>'.$term.'</B>입니다.';
    }

    return $str;
  }

  ## get sun position at unix timestamp
  ##
  ## [limit]
  ##  - mktime(0,0,0,1,1,1902) < $utime < mktime(23,59,59,12,31,2037)
  ##
  ## [study]
  ##  - w = 23.436
  ##  - tan RA = (sin L * cos w - tan e * sin w ) / cos L
  ##  - sin d = (sin e * cos w) + (cos e * sin w * sin L)
  ##
  ## [example]
  ##  - print_r(solar::sun(mktime(  10,0,0,3,21,2003)  ));
  ##  - print_r(solar::sun(mktime(10-9,0,0,3,21,2003),1)); // same as
  ##
  function &sun($utime, $GMT=FALSE)
  {
    $L = $D = $JD = 0; $J = '';
    $deg2rad = array();

    /***
    if($utime<-2145947400 || $utime>2145884399)
    {
        echo "\nerror: invalid input $utime, 1902.01.01 00:00:00 <= utime <= 2037.12.31 23:59:59\n";
        return -1;
    }
    ***/

    list($L,$atime) = solar::sunl($utime,$GMT,&$D,&$JD,&$J,&$deg2rad);

    ## Sun's ecliptic, in degress
    ##
    $e = sprintf('%.10f',23.439 - (0.00000036*$D)); // degress

    $cosg = cos($deg2rad['g']); // degress
    $cos2g = cos($deg2rad['2g']); // degress

    ## R == AU (sun ~ earth)
    ## The distance of the Sun from the Earth, R, in astronomical units (AU)
    ##
    $R = sprintf('%.10f',1.00014 - (0.01671*$cosg) - (0.00014*$cos2g));

    ## convert
    ##
    $deg2rad['e'] = deg2rad($e); // radian
    $deg2rad['L'] = deg2rad($L); // radian

    $cose = cos($deg2rad['e']); // degress
    $sinL = sin($deg2rad['L']); // degress
    $cosL = cos($deg2rad['L']); // degress
    $sine = sin($deg2rad['e']); // degress

    ## the Sun's right ascension(RA)
     ##
    //$tanRA = sprintf('%.10f',$cose * $sinL / $cosL); // degress
    //$RA = sprintf('%.10f',rad2deg(atan($tanRA)));
    //$RA = $cosL<0 ? $RA+180 : ($sinL<0 ? $RA+360 : $RA); // patch 2005.01.18
    $RA = sprintf('%.10f',rad2deg(atan2($cose*$sinL,$cosL)));
    $RA = solar::deg2valid($RA);

    ## the Sun's declination(d)
    ##
    $sind = sprintf('%.10f',$sine * $sinL); // degress
    $d = sprintf('%.10f',rad2deg(asin($sind))); // Sun's declination, degress

    $solartime = solar::deg2solartime($L);
    $daytime = solar::deg2daytime($RA);

    //if(!($L1=round($L) % 15))
    //{
    //    $idx = $L1 / 15;
    //    list($hterms) = solar::gterms();
    //}

    ## all base degress or decimal
    ##
     return array
    (
    'JD' => $JD,    /*** Julian Day ***/
    'J'  => 'J'.$J, // Jxxxx.xxxx format
    'L'  => $L,    /*** Sun's geocentric apparent ecliptic longitude ***/
    'e'  => $e,    /*** Sun's ecliptic ***/
    'R'  => $R,    /*** Sun from the Earth, astronomical units (AU) ***/
    'RA' => $RA,    /*** Sun's right ascension ***/
    'd'  => $d,    /*** Sun's declination ***/
    'stime'  => $solartime,        /*** solar time ***/
    'dtime'  => $daytime,        /*** day time ***/
    'atime'  => $atime,        /*** append time for integer degress **/
    'utime'  => $utime,        /*** unix timestamp ***/
    'date'   => calendar123::_date('D, d M Y H:i:s T',$utime),    /*** KST date ***/
    'gmdate' => calendar123::_date('D, d M Y H:i:s ',$utime-date('Z')).'GMT',    /*** GMT date ***/
    '_L'  => solar::deg2angle($L),
    '_e'  => solar::deg2angle($e,1),
    '_RA' => solar::deg2angle($RA),
    '_d'  => solar::deg2angle($d,1),
    '_stime' => solar::time2stime($solartime),
    '_dtime' => solar::time2stime($daytime),
    '_atime' => solar::time2stime($atime,TRUE),
    );
  }

  function &sunl($utime, $GMT=FALSE, $D=0, $JD=0, $J='', $deg2rad=array())
  {
    if($GMT) $utime += 32400; // force GMT to static KST, see 946727936

    ## D -- get the number of days from base JD
    ## D = JD(Julian Day) - 2451545.0, base JD(J2000.0)
    ##
    ## base position (J2000.0), 2000-01-01 12:00:00, UT
    ## as   mktime(12,0,0-64,1,1,2000) == 946695536 unix timestamp at KST
    ## as gmmktime(12,0,0-64,1,1,2000) == 946727936 unix timestamp at GMT
    ##
    $D = $utime - 946727936; // number of time
    $D = sprintf('%.10f',$D/86400); // float, number of days
    $JD = sprintf('%.10f',$D+2451545.0); // float, Julian Day
    $J = sprintf('%.4f',2000.0 + ($JD-2451545.0)/365.25); // Jxxxx.xxxx format

    $g = sprintf('%.10f',357.529 + (0.98560028 * $D));
    $q = sprintf('%.10f',280.459 + (0.98564736 * $D));

    ## fixed
    ##
    $g = solar::deg2valid($g); // to valid degress
    $q = solar::deg2valid($q); // to valid degress

    ## convert
    ##
    $deg2rad = array();
    $deg2rad['g'] = deg2rad($g); // radian
    $deg2rad['2g'] = deg2rad($g*2); // radian

    $sing = sin($deg2rad['g']); // degress
    $sin2g = sin($deg2rad['2g']); // degress

    ## L is an approximation to the Sun's geocentric apparent ecliptic longitude
    ##
    $L = sprintf('%.10f',$q + (1.915 * $sing) + (0.020*$sin2g));
    $L = solar::deg2valid($L); // degress
    $atime = solar::deg2solartime(round($L)-$L); // float

    return array($L,$atime); // array, float degress, float seconds
  }

  /***
  function &_atime($utime)
  {
    static $unit = 87658.1256;

    list($L) = solar::sunl($utime);
    $td = round($L) - $L;

    while(abs($td) > 0.0000114) // 1/$unit
    {
        $utime += $unit * $td;
        list($L) = solar::sunl($utime);
        $td = round($L) - $L;
    }

    return $utime;
  }
  ***/

  /***
  function &sinl($f, $v)
  {
    return sin(deg2rad($f+$v));
  }

  ## http://linux-sarang.net/board/?p=read&table=qa&no=198189
  ## -2 < sin x < + 2
  ## sin (77 + L) ==> (77 + L - 1.915 sin (77 + L))
  ##
  function &l2d($L)
  {
    $L = (int)$L; // 0 <= $L <= 345
    //$sinl  = sin(deg2rad(77+$L));
    $sinl = solar::sinl($L,77);
    //$sinl = solar::sinl($L-(1.915)*$sinl,77);

    //$sin2l = sin(deg2rad(154+($L*2)));
    $sin2l = solar::sinl($L*2,154);
    $sin2l = solar::sinl($L-(0.020*$L*2*$sin2l),154);
    $sin2l = solar::sinl($L-(0.020*$L*2*$sin2l),154);

    $D = sprintf('%.10f',($L - 280.459 - (1.915 * $sinl) - (0.020 * $sin2l)) / 0.98564736);

    return $D; // float
  }

  function &l2jd($L)
  {
    $D  = solar::l2d($L);
    $JD = sprintf('%.10f',$D+2451545.0);
    //$JD = $JD + ($i * 360 / 0.98564736)

    return $JD; // float
  }

  function &l2utime($year, $L, $GMT=FLASE)
  {
    $i = (int)$year - 2000 + 1;
    $D = solar::l2d($L);

    $utime = ($D * 86400) + 946727936 + (31556925.216 * $i);
    $utime = round($utime);

    return $utime - ($GMT ? 32400 : 0); // integer
  }
  ***/

  ## 1 hour == 15 degress
  ## 1 degress == 4 minute == 240 seconds
  ##
  function &deg2daytime($deg)
  {
    return sprintf('%.4f',$deg*240); // seconds
  }

  ## 1 solar year == 365.242190 days == 31556925.216 seconds
  ## 1 degress == 31556925.216 seconds / 360 degress == 87658.1256 seconds
  ##
  function &deg2solartime($deg)
  {
    return sprintf('%.4f',$deg*87658.1256); // seconds
  }

  function &deg2angle($deg, $singed=FALSE)
  {
    if($singed) $singed = '+';
    if($deg <0) { $singed = '-'; $deg = abs($deg); }

    $time = sprintf('%.4f',$deg*3600);
    $degr = (int)$deg.chr(161).chr(198); //sprintf('%d',$deg);
    $time = sprintf('%.4f',$time-($degr*3600)); // fmod
    $mins = sprintf('%02d',$time/60).chr(161).chr(199);
    $secs = sprintf('%.4f',$time-($mins*60)).chr(161).chr(200); // fmod

    return $singed.$degr.$mins.$secs;
  }

  function &deg2valid($deg)
  {
    //if($deg <= 360 && $deg >=0) return $deg;
    $deg = ($deg>=0) ? fmod($deg,360) : fmod($deg,360)+360.0;

    return (float)$deg; // float degress
  }

  function &moon2valid($moon)
  {
    //$moon = max($moon,1);
    //$moon = min($moon,12);

    if($moon < 1) $moon = 1;
    else if($moon > 12) $moon = 12;

    return (int)$moon;
  }

  function &time2stime($time, $singed=FALSE)
  {
    if($singed) $singed = '+';
    if($time<0) { $singed = '-'; $time = abs($time); }

    return $singed.calendar123::_date('z H i s',$time-date('Z'));
  }

  function &gterms()
  {
    static $hterms = array
    (
    '소한','대한','입춘','우수','경칩','춘분','청명','곡우',
    '입하','소만','망종','하지','소서','대서','입추','처서',
    '백로','추분','한로','상강','입동','소설','대설','동지'
    );

    static $tterms = array
    (
    -6418939, -5146737, -3871136, -2589569, -1299777,        0,
     1310827,  2633103,  3966413,  5309605,  6660762,  8017383,
     9376511, 10735018, 12089855, 13438199, 14777792, 16107008,
    17424841, 18731368, 20027093, 21313452, 22592403, 23866369
    );

    ## mktime(7+9,36,19-64,3,20,2000), 2000-03-20 16:35:15(KST)
    ##
    if(!defined('__SOLAR_START__'))
    {
    define('__SOLAR_START__',953537715); // start base unix timestamp
    define('__SOLAR_TYEAR__',31556940); // tropicalyear to seconds
    define('__SOLAR_BYEAR__',2000); // start base year
    }

    return array($hterms,$tterms);
  }

  function &tterms($year)
  {
    static $addstime = array
    (
    1902=> 1545, 1903=> 1734, 1904=> 1740, 1906=>  475, 1907=>  432,
    1908=>  480, 1909=>  462, 1915=> -370, 1916=> -332, 1918=> -335,
    1919=> -263, 1925=>  340, 1927=>  344, 1928=> 2133, 1929=> 2112,
    1930=> 2100, 1931=> 1858, 1936=> -400, 1937=> -400, 1938=> -342,
    1939=> -300, 1944=>  365, 1945=>  380, 1946=>  400, 1947=>  200,
    1948=>  244, 1953=> -266, 1954=> 2600, 1955=> 3168, 1956=> 3218,
    1957=> 3366, 1958=> 3300, 1959=> 3483, 1960=> 2386, 1961=> 3015,
    1962=> 2090, 1963=> 2090, 1964=> 2264, 1965=> 2370, 1966=> 2185,
    1967=> 2144, 1968=> 1526, 1971=> -393, 1972=> -430, 1973=> -445,
    1974=> -543, 1975=> -393, 1980=>  300, 1981=>  490, 1982=>  400,
    1983=>  445, 1984=>  393, 1987=>-1530, 1988=>-1600, 1990=> -362,
    1991=> -366, 1992=> -400, 1993=> -449, 1994=> -321, 1995=> -344,
    1999=>  356, 2000=>  480, 2001=>  483, 2002=>  504, 2003=>  294,
    2007=> -206, 2008=> -314, 2009=> -466, 2010=> -416, 2011=> -457,
    2012=> -313, 2018=>  347, 2020=>  257, 2021=>  351, 2022=>  159,
    2023=>  177, 2026=> -134, 2027=> -340, 2028=> -382, 2029=> -320,
    2030=> -470, 2031=> -370, 2032=> -373, 2036=>  349, 2037=>  523,
    );

    static $addttime = array
    (
    1919=> array(14=>-160), 1939=> array(10=> -508),
    1953=> array( 0=> 220), 1954=> array( 1=>-2973),
    1982=> array(18=> 241), 1988=> array(13=>-2455),
    2013=> array( 6=> 356), 2031=> array(20=>  411),
    2023=> array( 0=>  399, 11=>-571),
    );

    return array($addstime[$year],$addttime[$year]);
  }

  ## get the 24 solar terms, 1902 ~ 2037
  ##
  ## [usage]
  ##  - array solar::terms(int year [, int smoon [, int length [, array &sun]]] )
  ##
  function &terms($year=0, $smoon=1, $length=12, $sun=array())
  {
    $year  = (int)$year;
    $sun = array();
    $smoon = (int)$smoon;
    $length = (int)$length;
    $times = array();

    if(!$year) $year = date('Y');

    /***
    if($year<1902 || $year>2037)
    {
        echo "\nerror: invalid input $year, 1902 <= year <= 2037\n";
        return -1;
    }
    ***/

    list($hterms,$tterms) = solar::gterms();
    list($addstime,$addttime) = solar::tterms($year);

    ## mktime(7+9,36,19-64,3,20,2000), 2000-03-20 16:35:15(KST)
    ##
    $start = __SOLAR_START__; // start base unix timestamp
    $tyear = __SOLAR_TYEAR__; // tropicalyear to seconds
    $byear = __SOLAR_BYEAR__; // start base year

    $start += ($year - $byear) * $tyear;

    if($length < -12) $length = -12;
    else if($length > 12) $length = 12;

    $smoon = solar::moon2valid($smoon);
    $emoon = solar::moon2valid($smoon+$length);

    $sidx =  (min($smoon,$emoon) - 1) * 2;
    $eidx = ((max($smoon,$emoon) - 1) * 2) + 1;

    for($i=$sidx; $i<=$eidx; $i++)
    {
        $time = $start + $tterms[$i];
        list(,$atime) = solar::sunl($time,FALSE);
        $time += $atime + $addstime + $addttime[$i]; // re-fixed
        $terms[calendar123::_date('nd',$time)] = &$hterms[$i];
        $times[] = $time; // fixed utime
    }

    ## for detail information
    ##
    if(func_num_args() > 3)
    {
        $i = $sidx;
        foreach($times AS $time)
        {
            $sun[$i] = solar::sun($time,FALSE);
            $sun[$i]['_avgdate'] = calendar123::_date('D, d M Y H:i:s ',$start+$tterms[$i]-date('Z')).'GMT';
            $sun[$i]['_name'] = &$hterms[$i];
            $i++;
        }
    }

    unset($times);

    return $terms; // array
  }

  ## public, get a Constellation of zodiac
  ##
  function &zodiac($y, $m, $d)
  {
    static $ffd = array // patch day
    (
    19030622 => -24, 19221222 =>   4, 19540420 => -61, 19550723 => -48,
    19551222 => -57, 19560320 => -48, 19580823 => -52, 19600219 => -55,
    19610221 => -59, 19620823 => -37, 19651023 => -42, 19870525 =>  64,
    19880722 =>  61, 20230621 =>   4, 20300218 =>   7
    );

    $horoscope = array // do not set `static' variable, it's a bug?
    (
    array(chr(191).chr(176).chr(188).chr(210),'Capricon'),
    array(chr(200).chr(178).chr(188).chr(210),'Taurus'),
    array(chr(189).chr(214).chr(181).chr(213).chr(192).chr(204),'Gemini'),
    array(chr(176).chr(212),'Cancer'),
    array(chr(187).chr(231).chr(192).chr(218),'Leo'),
    array(chr(195).chr(179).chr(179).chr(224),'Virgo'),
    array(chr(195).chr(181).chr(196).chr(170),'Libra'),
    array(chr(192).chr(252).chr(176).chr(165),'Scorpius'),
    array(chr(177).chr(195).chr(188).chr(246),'Sagittarius'),
    array(chr(187).chr(234).chr(190).chr(231),'Aries'),
    array(chr(185).chr(176).chr(186).chr(180),'Aquarius'),
    array(chr(185).chr(176).chr(176).chr(237).chr(177).chr(226),'Pisces')
    );

    //list(,$nd) = _solar::_terms($y,$m,0);
    //$idx = ($m.$d<$nd) ? $m-2 : $m-1;
    //if($idx < 0) $idx += 12;

    $fk = sprintf('%d%02d%d',$y,$m,$d);
    list($L) = solar::sunl(calendar123::_mktime(23,59+(int)$ffd[$fk],59,$m,$d,$y));

    return $horoscope[floor($L/30)];
  }

  ## public, get sunrise, sunset on Korea
  ##
  ## same as PHP5 `date_sunrise()', `date_sunset()'
  ## http://williams.best.vwh.net/sunrise_sunset_example.htm
  ## http://kr.php.net/manual/en/function.date-sunrise.php
  ##
  ## [zenith]
  ##  offical      = 90 degrees 50'
  ##  civil        = 96 degrees
  ##  nautical     = 102 degrees
  ##  astronomical = 108 degrees
  ##
  function sunrise_sunset($_y, $_m, $_d, $_location=0, $_zenith=0)
  {
    static $_locations = array
    (
    array(126.95,37.55)/* 서울 */, array(131.87,37.24)/* 독도 */,
    array(129.37,36.04)/* 포항 */, array(126.35,36.52)/* 안면 */,
    );

    static $_zeniths = array(90.8333, 96.0, 102.0, 108.0);
    static $_timezone = 9.0; // KST +9H

    ## check arguments
    ##
    if(!preg_match('/^[0-3]$/',$_location)) $_location = 0;
    if(!preg_match('/^[0-3]$/',$_zenith)) $_zenith = 0;

    ## inital configurations
    ##
    $location  = $_locations[$_location];
    $longitude = $location[0];
    $latitude  = deg2rad($location[1]);
    $zenith    = deg2rad($_zeniths[$_zenith]);

    ## 1. first calculate the day of the year
    ##
    $N = floor(275*$_m/9) - (floor(($_m+9)/12) * (1+floor(($_y-4*floor($_y/4)+2)/3))) + $_d - 30;

    ## 2. convert the longitude to hour value and calculate an approximate time
    ##
    $lhour = $longitude / 15;
    $t['r'] = sprintf('%.8f',$N+((6-$lhour)/24.0)); // sunrise
    $t['s'] = sprintf('%.8f',$N+((18-$lhour)/24.0)); // sunrise

    ## 3. calculate the Sun's mean anomaly
    ##
    $M['r'] = (0.9856*$t['r']) - 3.289;
    $M['s'] = (0.9856*$t['s']) - 3.289;

    ## 4. calculate the Sun's true longitude
    ## to be adjusted into the range [0,360) by adding/subtracting 360
    ##
    $L['r'] = $M['r'] + (1.916*sin(deg2rad($M['r']))) + (0.020*sin(deg2rad(2*$M['r']))) + 282.634;
    $L['s'] = $M['s'] + (1.916*sin(deg2rad($M['s']))) + (0.020*sin(deg2rad(2*$M['s']))) + 282.634;
    $L['r'] = ($L['r']>=0) ? fmod($L['r'],360) : fmod($L['r'],360)+360.0;
    $L['s'] = ($L['s']>=0) ? fmod($L['s'],360) : fmod($L['s'],360)+360.0;
    $l['r'] = deg2rad($L['r']);
    $l['s'] = deg2rad($L['s']);

    ## 5a. calculate the Sun's right ascension
    ## to be adjusted into the range [0,360) by adding/subtracting 360
    ##
    $RA['r'] = rad2deg(atan(0.91764*tan($l['r'])));
    $RA['s'] = rad2deg(atan(0.91764*tan($l['s'])));
    $RA['r'] = ($RA['r']>=0) ? fmod($RA['r'],360) : fmod($RA['r'],360)+360.0;
    $RA['s'] = ($RA['s']>=0) ? fmod($RA['s'],360) : fmod($RA['s'],360)+360.0;

    ## 5b. right ascension value needs to be in the same quadrant as L
    ##
    $RA['r'] += (floor($L['r']/90.0)*90.0) - (floor($RA['r']/90.0)*90.0);
    $RA['s'] += (floor($L['s']/90.0)*90.0) - (floor($RA['s']/90.0)*90.0);

    ## 5c. right ascension value needs to be converted into hours
    ##
    $RA['r'] /= 15;
    $RA['s'] /= 15;

    ## 6. calculate the Sun's declination
    ##
    $sindec['r'] = 0.39782 * sin($l['r']);
    $sindec['s'] = 0.39782 * sin($l['s']);
    $cosdec['r'] = cos(asin($sindec['r']));
    $cosdec['s'] = cos(asin($sindec['s']));

    ## 7a. calculate the Sun's local hour angle
    ## (cosH> 1) the sun never rises on this location (on the specified date)
    ## (cosH<-1) the sun never sets on this location (on the specified date)
    ##
    $cosH['r'] = (cos($zenith) - ($sindec['r']*sin($latitude))) / ($cosdec['r']*cos($latitude));
    $cosH['s'] = (cos($zenith) - ($sindec['s']*sin($latitude))) / ($cosdec['s']*cos($latitude));

    ## 7b. finish calculating H and convert into hours
    ##
    $H['r'] = 360.0 - rad2deg(acos($cosH['r']));
    $H['s'] = rad2deg(acos($cosH['s']));
    $H['r'] /= 15;
    $H['s'] /= 15;

    ## 8. calculate local mean time of rising/setting
    ##
    $T['r'] = $H['r'] + $RA['r'] - (0.06571*$t['r']) - 6.622;
    $T['s'] = $H['s'] + $RA['s'] - (0.06571*$t['s']) - 6.622;

    ## 9. adjust back to UTC
    ## to be adjusted into the range [0,24) by adding/subtracting 24
    ##
    $UT['r'] = $T['r'] - $lhour;
    $UT['s'] = $T['s'] - $lhour;
    $UT['r'] = ($UT['r']>=0) ? fmod($UT['r'],24.0) : fmod($UT['r'],24.0) + 24.0;
    $UT['s'] = ($UT['s']>=0) ? fmod($UT['s'],24.0) : fmod($UT['s'],24.0) + 24.0;

    ## 10. convert UT value to local time zone of latitude/longitude
    ##
    $localT['r'] = fmod($UT['r']+$_timezone,24.0);
    $localT['s'] = fmod($UT['s']+$_timezone,24.0);

    ## last convert localT to human time
    ##
    $sunrise['H'] = floor($localT['r']);
    $sunrise['m'] = (int)(($localT['r']-$sunrise['H'])*60);
    $sunset['H'] = floor($localT['s']);
    $sunset['m'] = (int)(($localT['s']-$sunset['H'])*60);

    return array
    (
    sprintf('%02d',$sunrise['H']).':'.sprintf('%02d',$sunrise['m']), // sunrise HH:MM
    sprintf('%02d',$sunset['H']).':'.sprintf('%02d',$sunset['m']), // sunset HH:MM
    );
  }
} // end of class

/*** example ***
require_once 'class.calendar.php';
require_once 'class.solar.php';
$sun = array();
$terms = solar::terms(date('Y'),1,12,&$sun);
print_r($terms);
print_r($sun);
print_r(solar::sun(time()));
echo solar::today()."\n";
echo solar::solar(mktime(0,0,0,3,20))."\n";
echo solar::solar(mktime(0,0,0,3,21))."\n";
echo solar::solar(mktime(0,0,0,3,22))."\n";
echo "\n\n";
print_r(solar::terms(2023));
***/
?>
<!--//  Class 함수 인쿨르드 끝 -->

<!--//  function 인쿨르드: 파일 확장자가 "html" 이어야만 정상작동(php는 안됨), 또 class함수는 작동안됨-->
<!--#include("function/function_standard.html")-->
<!--//  인쿨르드 끝 -->

<!--// 날자 설정 ---------------------------------- -->
<?php
// Daylight saving time을 위해 Time zone을 지정할 수 있음 ( php4.대에서는 에러 발생, php5.1 이상에서 정상작동)
// date_default_timezone_set('America/Toronto'); // 타임존목록 http://kr.php.net/manual/kr/timezones.php )예: America/Toronto
$server_timestamp = mktime(date("H"), date("i"), date("s"), date("m"), date("d"), date("Y"));
$server_offset = date("Z");
$xe_timestamp = fn_xetimestamp();
$xe_offset = date("Z")+zgap();
$client_offset = Context::get('offset');        // url 변수로 받은 client offset  
$__Context->client_timestamp = $client_timestamp = mktime(date("H"), date("i"), date("s")-date("Z")+$client_offset, date("m"), date("d"), date("Y"));

// 화면에 보여줄 서버시간: 기본 XE시간으로 설정, 만약 default_timezone을 사용할 경우는 $server_timestamp, $server_offset 로 변경
$__Context->display_timestamp = $display_timestamp = $xe_timestamp;  
$__Context->display_offset = $xe_offset;	    
//$__Context->display_timestamp = $display_timestamp = $server_timestamp;  
//$__Context->display_offset = $server_offset;	    

if ($client_offset == null ) {
	$wrk_timestamp = $display_timestamp;
} else {
	$wrk_timestamp = $client_timestamp;
}

if ($pYear == null ) {
	$pYear = date("Y", $wrk_timestamp);
}

if ($pMonth == null ) {
	$pMonth = date("n", $wrk_timestamp);
}

if ($pMon == null ) {
	$pMon = date("F", $wrk_timestamp);
}

if ($pDay == null ) {
	$pDay = date("j", $wrk_timestamp);
}

if ($pOption < 1 || $pOption > 3 ) {
	$pOption=1;		// 간지옵션
}

$__Context->pYear = $pYear =date("Y", mktime(0, 0, 0, $pMonth, 1, $pYear)); 
$__Context->pMonth = $pMonth =date("n", mktime(0, 0, 0, $pMonth, 1, $pYear));
$__Context->pMon = $pMon =date("F", mktime(0, 0, 0, $pMonth, 1, $pYear));

$todayYY = date("Y", $wrk_timestamp);	// 당일년도
$todayMM = date("n", $wrk_timestamp);	// 당일월
$todayDD = date("j", $wrk_timestamp);	// 당일일
$__Context->wrk_timestamp = $wrk_timestamp;
?>

<?php 
$Calmain = fn_CalMain($pYear,$pMonth);		// 달력일자
$Holiday = fn_HolidayChk($pYear, $pMonth);		// 휴일(달력일자 붉은색표시를 위해..)
?>
<!--@if($module_info->display_holiday == 'Y')-->
<?php 
//$Holiday = fn_HolidayChk($pYear, $pMonth);      // 휴일 
$ind_holiday = "Y";
?>
<!--@end-->
<!--@if($module_info->display_memday == 'Y')-->
<?php 
$Memday = fn_MemdayChk($pYear, $pMonth);      // 기념일  
$ind_memday = "Y";
?>
<!--@end-->
<!--@if($module_info->display_lunar == 'Y')-->
<?php 
$Lunarday = fn_sol2lun_ary($pYear,$pMonth);   // 음력일자 - 1,10,20일
$ind_lunar = "Y";
?>
<!--@end-->
<!--@if($module_info->display_lunar == 'Y_all')-->
<?php 
$Lunarday = fn_sol2lun_ary($pYear,$pMonth);   // 음력일자 - 모든날자
$ind_lunar_all = "Y";
?>
<!--@end-->
<!--@if($module_info->display_24term == 'Y' || $module_info->display_iljin == 'Y')-->
<?php 
$sun = array();
$terms = solar::terms($pYear,1,12,&$sun);
$GanjiJeolki = fn_jeolki_ganji_ary($pYear,$terms,$pOption);     // 간지 절기
?>
<!--@end-->
<!--@if($module_info->display_24term == 'Y')-->
<?php 
$ind_24term = "Y";
?>
<!--@end-->
<!--@if($module_info->display_iljin == 'Y')-->
<?php 
$ind_iljin = "Y";
?>
<!--@end-->

<?php 
$ind_use_category = $__Context->module_info->use_category;				// 분류(카테고리) 사용여부
$ind_bgcolor_option = $__Context->module_info->use_category_bgcolor;	// 일정 배경색상 옵션
$ind_image_diary = $__Context->module_info->image_diary;				// 그림일기 사용여부
$ind_complete_doc = $__Context->module_info->display_complete_doc;		// 완료일정 표시여부
$ind_duplicated_schedule = $__Context->module_info->duplicated_schedule; // 중복일정 허용여부
?>

<!--// planner123 문서목록 얻기---------------------------------- -->
<!--// 검색년월 및 목록수 설정------ -->
<?php
$__Context->pYear = $pYear;					
$tempmonth = substr("0".$pMonth, -2);				//월 을 "7" 에서 "07"로
$__Context->tempMonth = $tempmonth;
$list_count = $__Context->module_info->list_count;  //목록수
$page_count = $__Context->module_info->page_count;  //목록수
?>

<!--// 검색필드 설정------ -->
<?php
$search_target = $__Context->search_target;
$search_keyword = $__Context->search_keyword;

// 검색 Target에 따른 검색필드 설정.
if ($search_keyword != null) {
	switch ($search_target) {
      case (title):
		$obj->var_search_title = $search_keyword;
        break;
      case (content):
		$obj->var_search_content = $search_keyword;
        break;
      case (title_content):
		$obj->var_search_title = $search_keyword;
		$obj->var_search_content = $search_keyword;
        break;
//      case (comment):   // 댓글 검색하지 않음
//        $obj->var_search_comment = $search_keyword;
//        break;
      case (user_name):
        $obj->var_search_user_name = $search_keyword;
        break;
      case (nick_name):
        $obj->var_search_nick_name = $search_keyword;
        break;
      case (user_id):
        $obj->var_search_user_id = $search_keyword;
        break;
      case (tag):
        $obj->var_search_tags = $search_keyword;
        break;
      default :
         if(strpos($search_target,'extra_vars')!==false) {
            $obj->var_search_extra_idx = substr($search_target, strlen('extra_vars'));
            $obj->var_search_extra_value = str_replace(' ','%',$search_keyword);
         }
         break;
    }
}
?>

<!--// 분류필드 설정--- -->
<!--@if($module_info->use_category == "Y")-->
<?php
$tmp_category = Context::get('category_list');  // 분류srl 얻기 (1단계만 지원, 그룹제한 고려 않음)
if (!$tmp_category) {
	$tmp_category = array();
}
$wrk_var_category_srl = "0";					// 디폴트
foreach ($tmp_category as $val) {
	$wrk_var_category_srl .= ",".$val->category_srl;
    if ($val->selected) {
	    $obj->var_category_srl = $val->category_srl;
	}
}
if (!$obj->var_category_srl) {
$obj->var_category_srl = $wrk_var_category_srl;
}
?>
<!--@end-->

<!--// loged member --- -->
<?php
// $member_temp_name = $__Context->logged_info->nick_name; // 공개그룹 user에 nick_name 이용
$member_temp_name = $__Context->logged_info->user_name; //  공개그룹 user에 user_name 이용
$member_srl = $__Context->logged_info->member_srl;
$group_list = $__Context->logged_info->group_list;
$usergroup_arr = array();
if ($member_srl != null) {
	$obj->var_member_srl = $member_srl;	 // user srl
    foreach($group_list as $key => $val) {
       $group_titles .= ",".$val;
	}
    $group_titles=substr($group_titles,1);    // 사용자가 소속된 그룹명칭
	$usergroup_arr = explode(",",$group_titles);
} 
?>

<!--// 쿼리 설정/실행/list만들기--- -->
<?php
$obj->site_srl = '';  // 0을 넣으면 이상해짐
$obj->module_srl = $__Context->module_info->module_srl;
$obj->sort_index_1 = 'extra_value_end';	// (일정시작 일) start를 end로(2010-08-01)
$obj->order_type_1 = 'desc';
$obj->sort_index_default_1 = 'extra_value_start';	
$obj->sort_index_2 = 'extra_value_time';	// (시작종료 시간)
$obj->order_type_2 = 'asc';
$obj->sort_index_default_2 = 'extra_value_time';
$obj->sort_index = $__Context->module_info->order_target;	// (게시판 문서 정렬 번호)
$obj->order_type = $__Context->module_info->order_type;
$obj->sort_index_default = 'list_order';	// 게시판설정 선택값이 null 일때
$obj->list_count = $list_count*10;  // 게시판 설정값 10배의 일정표시 (예:기본 20일때 200개까지)
$obj->page_count = $page_count;  // 게시판 설정값
$obj->var_idx1 = '1';    // 확장변수1번: sort target(일정시작)- 통상 값이 있음
$obj->var_idx2 = '2';	 // 확장변수2번: sort targer(일정종료)- 대부분의 경우 null 값임
$obj->var_idx7 = '7';	 // 확장변수7번: 시작종료시간
$obj->var_idx8 = '8';	 // 확장변수8번: 공개그룹
$obj->var_period_start = $pYear.$tempmonth."01";	 // 선택 범위시작 - 당월 01일 >=
$obj->var_period_end = $pYear.$tempmonth."31";	 // 선택 범위  끝 - 당월 31일 <=
$obj->var_fld_null = "0";	 // null 대신값 (null이면 이상해짐)

$query_path = $__Context->module_info->module."/skins/".$__Context->module_info->skin;       // 쿼리경로
$view_group = $__Context->module_info->default_document_group;    // 스킨에서 정해준 일반사용자가 볼수있는 문서그룹

if ($__Context->grant->manager) {
	$output = executeQueryArray($query_path.'.getDocumentsForPlanner_all', $obj);    // 관리자 (모든문서)
} else if ($__Context->module_info->consultation == "Y") {
	$output = executeQueryArray($query_path.'.getDocumentsForPlanner_own', $obj);    // 상담기능 (자신 + 공지)
} else if ($view_group == "owner") {
	$output = executeQueryArray($query_path.'.getDocumentsForPlanner_own', $obj);    // 자신 + 공지
} else if ($view_group == "usergroup") {
	$output = executeQueryArray($query_path.'.getDocumentsForPlanner_group', $obj);  // 자신 + 공지 + 공개그룹소속
} else if ($view_group == "nonsecured") {
	$output = executeQueryArray($query_path.'.getDocumentsForPlanner_nonSec', $obj); // 타인 비밀글및 비멤버쉽 문서 제외
} else if ($view_group == "alldocument") {
	$output = executeQueryArray($query_path.'.getDocumentsForPlanner_all', $obj);    // 모든문서
} else {
	$output = executeQueryArray($query_path.'.getDocumentsForPlanner_all', $obj);    // 모든문서
}

// ---문서 목록 생성 --
	if(count($output->data)) {
		foreach($output->data as $key => $attribute) {
			$tmp_document_srl = $attribute->document_srl;
			$tmp_Document = null;
			$tmp_Document = new documentItem();
			$tmp_Document->setAttribute($attribute, false);
			$tmp_Document->category_srl = $attribute->category_srl;
            $tmp_opengroup_arr = explode("|@|",$attribute->extra_value_group);

		  if($module_info->consultation == 'Y'){   // 상담기능 일때
			if ( $__Context->grant->manager) {
			    $tmp_document_list[$key] = $tmp_Document;       //상담기능-관리자이면 전체 문서를 처리,
			} else {
				if ($attribute->is_notice == "Y" || $attribute->member_srl == $member_srl) {
 			        $tmp_document_list[$key] = $tmp_Document;   //상담기능-관리자 아니면 공지문서나 자신의 문서이면 처리.
                }
			}
          } else {  // 상담기능 아닐때

			if ( $__Context->grant->manager || $view_group == "alldocument") {
			    $tmp_document_list[$key] = $tmp_Document;       // 관리자또는 문서그룹이 alldocument 이면 전체 문서를 처리,
			} else if ($view_group != "usergroup" && $attribute->extra_value_group == null) {
			    $tmp_document_list[$key] = $tmp_Document;       // 문서그룹이 usergroup이 아니면서 공개그룹을 선택하지 않은 문서 처리,
			} else {											// 문서그룹이 usergroup 또는 공개그룹 선택된 문서
				if ($attribute->is_notice == "Y" || $attribute->member_srl == $member_srl) {
 			        $tmp_document_list[$key] = $tmp_Document;       //공지문서나 자신의 문서이면 처리.
                } else {
                    $tmp_flag = "";
                    foreach($usergroup_arr as $tmp_key => $val_tmp) {
			    	    if (in_array($val_tmp, $tmp_opengroup_arr)){   
 			               $tmp_flag = "*";                        //공개그룹 소속.
						}
				    }
			    	if ($member_temp_name != null && in_array($member_temp_name, $tmp_opengroup_arr)){   //공개 user_name.
 						$tmp_flag = "*";                        
					}
				    if ($tmp_flag == "*") {
 			        $tmp_document_list[$key] = $tmp_Document;       //공개그룹 소속이면 처리.
                    }
			    }
			}  

		  }  //상담기능 아닐때 끝

		//echo $tmp_document_srl." ";  //디버깅용
		}  //foreeach 끝
	} else {
		$tmp_document_list = array();          
	}
$__Context->planner123_document_list = $tmp_document_list;
// ---문서 목록 생성 끝--
?>
<!--// planner123 문서목록 얻기 끝---------------------------------- -->

<!--// 공지사항과 일반문서 합치기 ($planner123_document_list로 대체함:만일을위해 살려둠)  -->
<!--@if($notice_list != null)-->
    {@ $planner_document_list = $notice_list}
    <!--@if($document_list != null)-->
        {@ $planner_document_list = $planner_document_list + $document_list}
    <!--@end-->
<!--@else-->
    {@ $planner_document_list = $document_list}
<!--@end-->

<!--// Xe 확장변수 변수를 작업 ($key 등은 board설정시 목록에 포함되어야 들어옴)  -->
<!--@foreach($planner123_document_list as $no => $document)-->

    <!--// Category title & color값 얻기  -->
    <!--@if($module_info->use_category == "Y" && $document->get('category_srl'))-->
        <!--@if($category_list[$document->get('category_srl')]->color)-->
        {@ $category_color = $category_list[$document->get('category_srl')]->color}
        <!--@end-->
        {@ $category_title = $category_list[$document->get('category_srl')]->title}
    <!--@else-->
        {@ $category_color = null}
        {@ $category_title = null}
    <!--@end-->
    <?php
        $category_title = $__Context->category_title;
        $category_color = $__Context->category_color;
    ?>

    <!--// 댓글 숫자 얻기  -->
    <!--@if($document->getCommentCount())-->
        {@ $plan_reply = $document->getCommentCount()}
    <!--@else-->
        {@ $plan_reply = null}
    <!--@end-->
    <?php
        $plan_reply = $__Context->plan_reply;
    ?>

    <!--// 확장변수값 얻기  -->
    <!--@foreach($list_config as $key => $val)-->
        <!--@if($val->idx == -1)-->
        <!--@else-->
            <!--@if($val->idx == 1)-->
            {@ $plan_start = $document->getExtraValue($val->idx)}
            {@ $startYY = substr($plan_start,0,4)}
            {@ $startMM = substr($plan_start,4,2)}
            {@ $startDD = substr($plan_start,6,2)}
            {@ $plan_title = $document->getTitle($module_info->subject_cut_size)}
            {@ $plan_detail = $document->getSummary($module_info->content_cut_size)}

			<!--@if($_COOKIE["mobile"])--> <!--// 모바일일때 그림 사이즈작게 mobile::isFromMobilePhone() 함수를 쿠키로 대체-->
            {@ $plan_img = $document->getThumbnail(45, 45, $module_info->thumbnail_type)}
			<!--@else-->
            {@ $plan_img = $document->getThumbnail($module_info->thumbnail_width, $module_info->thumbnail_height, $module_info->thumbnail_type)}
			<!--@endif-->

			{@ $plan_doc_extra_vars = $document->get('extra_vars')}    <!--// 취소일정을 위해 추가 -->
            {@ $plan_docurl = $document->document_srl}
			{@ $plan_url = getUrl('document_srl',$document->document_srl, 'listStyle', $listStyle, 'cpage','','offset',$offset)}
                <!--//@if($startYY == $pYear && $startMM == $tempMonth)-->
                <?php
                $plan_title = $__Context->plan_title;
                $plan_detail = $__Context->plan_detail;
                $plan_img = $__Context->plan_img;
                $plan_doc_extra_vars = $__Context->plan_doc_extra_vars;    <!--// 취소일정을 위해 추가 -->
                $plan_url = $__Context->plan_url;
                $plan_start = $__Context->plan_start;           // 일정시작
                $plnstartYY = $__Context->startYY;
                $plnstartMM = $__Context->startMM;
                $plnstartDD = $__Context->startDD;
                $plnstartMM = ltrim( $plnstartMM, "0" );    //  앞의 "0" 제거
                $plnstartDD = ltrim( $plnstartDD, "0" );    //  앞의 "0" 제거
                ?>
                <!--//@end-->
            <!--@end-->
            <!--@if($val->idx == 2 )-->
            {@ $plan_end = $document->getExtraValue($val->idx)}
                <!--@if($plan_end == null )-->
                {@ $plan_end = $plan_start}
                <!--@end-->
            {@ $endYY = substr($plan_end,0,4)}
            {@ $endMM = substr($plan_end,4,2)}
            {@ $endDD = substr($plan_end,6,2)}
                <!--//@if($endYY >= $pYear && $endMM >= $tempMonth)-->
                <?php
                $plan_end = $__Context->plan_end;           // 일정종료
                $plnendYY = $__Context->endYY;
                $plnendMM = $__Context->endMM;
                $plnendDD = $__Context->endDD;
                $plnendMM = ltrim( $plnendMM, "0" );    // 일자 앞의 "0" 제거
                $plnendDD = ltrim( $plnendDD, "0" );    // 일자 앞의 "0" 제거
                ?>
                <!--//@end-->
            <!--@end-->
            <!--@if($val->idx == 3 )-->
            {@ $plan_bgcolor = $document->getExtraValueHTML($val->idx)}
                <?php
                $plan_bgcolor = $__Context->plan_bgcolor;       // 배경색상
                ?>
            <!--@end-->
            <!--@if($val->idx == 4 )-->
            {@ $plan_flagicon = $document->getExtraValueHTML($val->idx)}
                <?php
                $plan_flagicon = $__Context->plan_flagicon;     // 일정확인
                ?>
            <!--@end-->
            <!--@if($val->idx == 5 )-->
            {@ $plan_repeat_cycle = $document->getExtraValueHTML($val->idx)}
                <?php
                $plan_repeat_cycle = $__Context->plan_repeat_cycle;     // 반복일정 cycle
                ?>
            <!--@end-->
            <!--@if($val->idx == 6 )-->
            {@ $plan_repeat_unit = $document->getExtraValueHTML($val->idx)}
                <?php
                $plan_repeat_unit = $__Context->plan_repeat_unit;       // 반복일정 unit
                ?>
            <!--@end-->
            <!--@if($val->idx == 7 )-->
            {@ $plan_time = $document->getExtraValueHTML($val->idx)}
                <?php
                $plan_time = $__Context->plan_time;						// 시간대 (09:00, 09:30, 10:00,.. 형식)
                ?>
            <!--@end-->
        <!--@end-->
    <!--@end-->

    <!--// 새글 이미지값 얻기  -->
    {@ $plan_new = $document->printExtraImages(60*60*$module_info->duration_new)}
    <?php $plan_new = $__Context->plan_new; ?>

<?php
if ($plnstartYY != null ) {
    if ($plnstartYY == $pYear && $plnstartMM == $pMonth) {     // 당월 시작 이면서 당월 이후 종료
        if ($plnendYY > $pYear || $plnendYY == $pYear && $plnendMM > $pMonth) {
                    $plnendYY = $pYear;
                    $plnendMM = $pMonth;
                    $plnendDD = 31;
        }
    }
    elseif ($plnstartYY < $pYear || $plnstartYY == $pYear && $plnstartMM < $pMonth) {  // 당월 이전 시작 이면서 당월 종료
        if ($plnendYY == $pYear && $plnendMM == $pMonth) {
                    $plnstartYY = $pYear;
                    $plnstartMM = $pMonth;
                    $plnstartDD = 1;
        }
        if ($plnendYY > $pYear || $plnendYY == $pYear && $plnendMM > $pMonth) { // 당월 이전시작 이면서 당월 이후 종료
                    $plnstartYY = $pYear;
                    $plnstartMM = $pMonth;
                    $plnstartDD = 1;
                    $plnendYY = $pYear;
                    $plnendMM = $pMonth;
                    $plnendDD = 31;
        }
    }

// qtip 미사용으로 인해 아래 3째줄 주석처리
	$plan_detail = str_replace("'", "`", $plan_detail);			// '을 `로 대체 textbox보이기위해
	$plan_detail = str_replace("\"", "&quot;", $plan_detail);	// "를 &quot;로 대체 textbox보이기위해
//	$plan_detail = str_replace(chr(012), "<br />", $plan_detail); // FF를 제거 textbox보이기위해
	$plan_detail = str_replace(chr(015), "", $plan_detail);		// SI을 제거 textbox보이기위해 -줄바꿈

	// 취소일정위해 추가
	// ('A'=>'기본', 'F'=>'완료', 'R'=>'취소');  // 기본: 최초는 null, 수정하면 A
	$_doc_extra_vars = explode(";", $plan_doc_extra_vars);
	$_doc_extra_vars1 = explode(":", $_doc_extra_vars[0]);
	$_doc_status = str_replace("\"", "", $_doc_extra_vars1[2]);

	if($_doc_status == "F" && $ind_complete_doc == "L") { $plan_title = "<span class='complete'>".$plan_title."</span>"; }  // 완료일정 제목에 취소선 긋기
	if($_doc_status != "R" && ($ind_complete_doc == "N" && $_doc_status != "F" || $ind_complete_doc != "N") ) {	// 취소일정이 아닐때 처리

    if( $plnstartYY == $pYear && $plnstartMM == $pMonth) {         // 일정관련자료 어레이에 출력
      $arr_repeat = fn_repeat_schedule($pYear, $pMonth, $plan_start, $plan_end, $plan_repeat_cycle, $plan_repeat_unit);
      For   ($i = $plnstartMM; $i <= $plnendMM; $i++) {
        For ($j = $plnstartDD; $j <= $plnendDD; $j++ ) {
            if ( $arr_repeat[$i][$j] == "*") {
                $arr_plan[$i][$j] = $arr_plan[$i][$j].$plan_title."|&Oslash;|".$plan_url."|&Oslash;|".$plan_detail."|&Oslash;|".$plan_bgcolor."|&Oslash;|".$plan_flagicon."|&Oslash;|".$category_title."|&Oslash;|".$category_color."|&Oslash;|".$plan_reply."|&Oslash;|".$plan_time."|&Oslash;|".$plan_new."|&Oslash;|".$plan_img."|#&Oslash;#|";   // 어레이에 추가 1차분리자= "|#&Oslash;#|", 2차 분리자 "|&Oslash;|"
            }
        }
      }
	}	// 일정관련자료 어레이에 출력 끝

	}   // 취소일정이 아닐때 처리 끝

}
?>
<!--@end-->

<!--// -----달력작성 ----------------------- -->
<style type="text/css">
/* {$var_version} */
.planner_calendar thead th { border:1px solid #ccc; height:27px; background: url(<?php echo $skinpath?>images/calendar/tablehd_bg.png) repeat-x; }
.planner_calendar tbody .today_bg { background:{$today_bgcolor}; border:medium solid; border-color:{$today_bodercolor}; }
.planner_calendar tbody .today_date_bg { background:{$today_bgcolor};}
</style>

<!--@if($device == big_size )--> <!--// for big_calendar -->
<style type="text/css">
#columnLeft, .columnLeft, .bloozLeft, .bread-left, .bread-crumb {display:none;}
#columnRight, .columnRight, #bloozLayout .bloozRight {background:none; width:100%;}
</style>
<!--@end-->

<!--@if($device == printer )--> <!--// for print -->
<style type="text/css">
body, #contentBody {color : #000000; background : #FFFFFF;}
#header, #footer, #columnLeft, .boardInformation {display:none;}

#top, #menu, .columnLeft, .bloozLeft, .bread-crumb, .bread-left, .boardInformation {display:none;}
#columnRight, .columnRight, #bloozLayout .bloozRight {background: #FFFFFF; width:100%; padding:0px; border:none;}

.planner_navigation {display:none;}
.planner_calendar tbody .today_bg { background:{$day_bgcolor}; border:1px solid #ccc;}
.planner_calendar tbody .today_date_bg { background:{$day_bgcolor};}
</style>
<!--@end-->

<div class="planner123">
    <!--//  버튼 -->
    <div class="planner_control">
        <div class="planner_this">
            <!--//숫자형식으로 년월 표시-->
            <!--//    <font size="4" COLOR=green><b><?php echo $pYear?>年 <?php echo $pMonth?>月&nbsp;&nbsp;(<?php echo $pYear+2333?>)</b></font>-->
            <!--//영문형식으로 년월 표시-->
            <?php echo $pMon?>&nbsp;&nbsp;<?php echo $pYear?>
		</div>
        <div class="planner_navigation">
			<form style="float:left; width:65px;" name = "fm_select_year">
			<select style ="height:17px; margin:0; padding:0; font-size:11px;" name="selectyear" onchange="document.location.href='<?php echo $linkpath?>&amp;pOption=<?php echo $pOption?>&amp;pYear=' + this.options[this.selectedIndex].value +'&amp;pMonth=<?php echo $pMonth?>'">
			<option value='<?php echo $pYear?>'><?php echo $pYear?></option>
			<?php for ($j=$todayYY+10; $j>=$todayYY-5; $j-- ) { echo ("<option value='".$j."'>".$j."</option>"); } ?>
			</select></form>
			<!--@if(!$_COOKIE["mobile"])-->
            <img  style="float:left;" src="images/calendar/month_t.gif" width="39" height="15" />
			<a href="<?php echo $linkpath?>&amp;pOption=<?php echo $pOption?>&amp;pYear=<?php echo $pYear?>&amp;pMonth=<?php echo $pMonth-1?>&amp;pDay="><img  style="float:left;" src="images/calendar/btn_prev_year.gif" width="17" height="15" alt="전월" /></a>
            <?php
            for ($i=1; $i < 13; $i++) {
            ?>
            <a style="float:left;" href="<?php echo $linkpath?>&amp;pOption=<?php echo $pOption?>&amp;pYear=<?php echo $pYear?>&amp;pMonth=<?php echo $i?>&amp;pDay="><img src="images/calendar/month_<?php echo $i?><?php IF($pMonth == $i){ ?>_on<?php }?>.gif" width="17" height="15" alt="<?php echo $i?>월" /></a>
            <?php
            }
            ?>
			<!--@else-->
			<a href="<?php echo $linkpath?>&amp;pOption=<?php echo $pOption?>&amp;pYear=<?php echo $pYear?>&amp;pMonth=<?php echo $pMonth-1?>&amp;pDay="><img  style="float:left;" src="images/calendar/btn_prev_year.gif" width="17" height="15" alt="전월" /></a>
            <span  style="float:left;">MONTH</span>
			<!--@endif-->
            <a style="float:left;" href="<?php echo $linkpath?>&amp;pOption=<?php echo $pOption?>&amp;pYear=<?php echo $pYear?>&amp;pMonth=<?php echo $pMonth+1?>"><img src="images/calendar/btn_next_year.gif" width="17" height="15" alt="익월" /></a>
        </div>
    </div>
    <!--//  달력 -->
    <table class="planner_calendar" summary="플래너123">
        <thead>
            <tr>
                <th scope="col" width="14%"><font color="red">Sun</font></th>
                <th scope="col" width="14%">Mon</th>
                <th scope="col" width="14%">Tue</th>
                <th scope="col" width="14%">Wed</th>
                <th scope="col" width="14%">Thu</th>
                <th scope="col" width="14%">Fri</th>
                <th scope="col" width="14%"><font color="blue">Sat</font></th>
            </tr>
        </thead>
        <tbody>

        <?php
        $weekcount = count($Calmain);
        for($i=0; $i<$weekcount; $i++) {
            echo ("<tr>\n");
            for ($j=0; $j<7; $j++) {
        ?>
                <td <?php if($pYear == $todayYY && $pMonth == $todayMM && $Calmain[$i][$j] == $todayDD) { ?> class='today_bg'  <?php } else { ?> bgcolor="{$day_bgcolor}"<?php } ?> onMouseOut="this.style.backgroundColor=''" onMouseOver="this.style.backgroundColor='{$mouseover_bgcolor}'">
                <ul class="planner_calendar_inner">
                <?php
                $tmpfld_1 = null;
                $outtext = null;
                $k = $Calmain[$i][$j];

                if ($Calmain[$i][$j]== "*"){
                    $Calmain[$i][$j]=null;
                    echo "<li></li>";
                }
                else
                {
                    $tempday=$Calmain[$i][$j];

                    // --해당일의 음력일자,절기,휴일,기념일 얻기---
                    $tmparr=explode("-",$Lunarday[$pMonth][$Calmain[$i][$j]]);  //음력날자
                    if ($tmparr[3] == "윤달") {
                        $youndal = "윤";
                    }
                    else {
                        $youndal = null;
                    }
                    $tmpfld1 ="(".$youndal.$tmparr[1]."-".$tmparr[2].")";

                    $tmparr2=explode("-",$GanjiJeolki[$pMonth][$Calmain[$i][$j]]);  //24절기

                    $tmparr4=explode("-",$Holiday[$pMonth][$Calmain[$i][$j]]);  // 공휴일
                    $tmparr5=explode("-",$Memday[$pMonth][$Calmain[$i][$j]]);   // 기념일

                    $tmparr6=explode("|#&Oslash;#|",$arr_plan[$pMonth][$Calmain[$i][$j]]);    // 일정/플랜  1차 "|#&Oslash;#|",로 분리

                    // 첫줄 --일자,음력,절기---
                    if ($pYear == $todayYY && $pMonth == $todayMM && $Calmain[$i][$j] == $todayDD ) {
                        $outtext = "<li class='today_date_bg'>";   // 당일
                    }
                    else  {
                        $outtext = "<li>";                 // 평일
                    }

                    if ($j==0 || $tmparr4[0] != null) {
                        $tmpfld = "<span class='holiday'>".$Calmain[$i][$j]."</span>";    // 일요일 및 휴일
                    }
                    elseif ($j==6) {
                        $tmpfld = "<span class='saturday'>".$Calmain[$i][$j]."</span>";   // 토요일
                    }
                    else  {
                        $tmpfld = "<span class='weekday'>".$Calmain[$i][$j]."</span>";  // 평일
                    }

					if ($ind_duplicated_schedule == 'N' && mktime(0,0,0,$pMonth,$Calmain[$i][$j],$pYear) < mktime(0,0,0,$todayMM,$todayDD,$todayYY) ) {  // 중복일정금지 및 과거일자 는 링크없이.
		               $templink = "<a href='#' class='strong font_big' style='cursor:no-drop;'>";		
					} else {
						$templink = getUrl('act','dispBoardWrite','document_srl','') ;  // 일자 클릭시 쓰기로 이동
		                $templink .= "&amp;extra_vars1=$pYear-$tempmonth-".substr("0".$tempday,-2);  // 일정시작 확장변수에 값 넣기위해
		                $templink = "<a href=".$templink." class='strong font_big'>";
					}
                    $outtext .= "&nbsp;".$templink.$tmpfld."</a>";   // 일자

                    if ($ind_lunar_all == 'Y' && $Calmain[$i][$j] != null) {	
                        $outtext .= "&nbsp;"."<span class='lunar'>".$tmpfld1."</span>";    // 음력 - 모든날자 표시
                    }
					if ($ind_lunar == 'Y' && ($tmparr[2] == 1 || $tmparr[2] == 10 || $tmparr[2] == 15 || $tmparr[2] == 20)) {  
                        $outtext .= "&nbsp;"."<span class='lunar'>".$tmpfld1."</span>";    // 음력 - 1,10,15,20일 표시
                    }
                    if ($ind_iljin == 'Y') {  // 일진 표시
						$outtext .= "&nbsp;"."<span class='lunar'>".substr($tmparr2[2], 0, 6)."</span>";    // 일진
					}
                    if ($ind_24term == 'Y') {  // 절기 표시
						$outtext .= "&nbsp<span class='seasons24 strong'>".$tmparr2[4]."</span>";   // 절기
					}
                    if ($ind_holiday == 'Y') {  // 휴일 표시
						$outtext .= "&nbsp;<span class='holiday strong'>".$tmparr4[0]."</span>"; // 공휴일
					}
                    $outtext .= "</li>";
                    echo ($outtext);

                   // 두째줄 --일정/플랜---
                    if (!empty($tmparr6[0]))
                    {
                        foreach ($tmparr6 as $val)
                        {
                            if (!$val = trim($val)) continue; // 빈어레이는 무시하고 빠진다.
                            $tmparr7=explode("|&Oslash;|",$val);  // 일정/플랜  2차 "|&Oslash;|",로 분리
                            if (!empty($tmparr7[0]))
                            {
                                //$lplan_cat = (!empty($tmparr7[5]))?"<span style='color:".$tmparr7[6].";'>[".$tmparr7[5]."] </span>":""; // 분류
								$lplan_state = null;
								if (!empty($tmparr7[4]))
								{
									$arr_icon = explode(",",$tmparr7[4]);
									foreach ($arr_icon as $icon)
									{
										if ($icon = trim($icon))
										{
											if (file_exists($skinpath."images/icon/".$icon)) {
											    $icon_folder = "";
											} else if (file_exists($skinpath."images/icon/client/".$icon)) {
											    $icon_folder = "client/";
											} else if (file_exists($skinpath."images/icon/manager/".$icon)) {
											    $icon_folder = "manager/";
											}
			                                $lplan_state .= "<img src='images/icon/".$icon_folder.$icon."'/>"; //일정확인
										}
									}
								}
                                //$lplan_reply = (!empty($tmparr7[7]))?"<span class='small'>[".$tmparr7[7]."]</span>":""; //댓글숫자

 								if ($ind_duplicated_schedule == "N") { // 중복금지 
									$time_disply_fld = "[".$tmparr7[8]."]&#x0A;";   //선택내용 전부
								} else {
									$tmp_time = explode(",",$tmparr7[8]);		
									if ($tmparr7[8]){ 
										if ($tmp_time[1]){
											$time_disply_fld = "[".$tmp_time[0]."-".trim($tmp_time[count($tmp_time)-1])."] ";  // 일정 시간
										} else {
											$time_disply_fld = "[".$tmp_time[0]."- ] ";  // 일정 시작시간
										}
									} else { 
										$time_disply_fld = null; 
									} //시간표시
								}

								// 배경색상 적용 옵션 반영 (단, 작성시 제목에 색상을 적용한 경우는 글자색이 그대로 유지됨)
								if ($ind_bgcolor_option == "picker_bg"){	// 선택색상을->배경색
									$tmp_style = "style='clear:both; background-color:".$tmparr7[3]."; border-bottom:1px solid #FFFFFF;'";
									$tmp_style1_0 = "style='float:left; background-color:".$tmparr7[3]."; border-bottom:1px solid #FFFFFF;'";
									$tmp_style1_1 = "style='padding:5px 0 0 5px; background-color:".$tmparr7[3]."; border:medium double  #FFFFFF;'";
									$tmp_style2 = "style='background-color:".$tmparr7[3].";'";
								} else if ($ind_bgcolor_option == "picker_text"){	// 선택색상을->글자색
									$tmp_style = "style='clear:both; color:".$tmparr7[3]."; border-bottom:1px solid #FFFFFF;'";
									$tmp_style1_0 = "style='float:left; color:".$tmparr7[3]."; border-bottom:1px solid #FFFFFF;'";
									$tmp_style1_1 = "style='padding:5px 0 0 5px; color:".$tmparr7[3]."; border:medium double ".$tmparr7[3].";'";
									$tmp_style2 = "style='color:".$tmparr7[3].";'";
								} else if ($ind_bgcolor_option == "category_bg" && $ind_use_category == "Y"){	// 분류색상을->배경색
									$tmp_style = "style='clear:both; color:whitesmoke; background-color:".$tmparr7[6]."; border-bottom:1px solid #FFFFFF;'";
									$tmp_style1_0 = "style='float:left; color:whitesmoke; background-color:".$tmparr7[6]."; border-bottom:1px solid #FFFFFF;'";
									$tmp_style1_1 = "style='padding:5px 0 0 5px; color:whitesmoke; background-color:".$tmparr7[6]."; border:medium double #FFFFFF;'";
									$tmp_style2 = "style='color:whitesmoke; background-color:".$tmparr7[6].";'";
								} else if ($ind_bgcolor_option == "category_text" && $ind_use_category == "Y"){	// 분류색상을->글자색
									$tmp_style = "style='clear:both; color:".$tmparr7[6]."; border-bottom:1px solid #FFFFFF;'";
									$tmp_style1_0 = "style='float:left; color:".$tmparr7[6]."; border-bottom:1px solid #FFFFFF;'";
									$tmp_style1_1 = "style='padding:5px 0 0 5px; color:".$tmparr7[6]."; border:medium double ".$tmparr7[6].";'";
									$tmp_style2 = "style='color:".$tmparr7[6].";'";
								}else {	// 기본은 선택색상->배경색
									$tmp_style = "style='clear:both; background-color:".$tmparr7[3]."; border-bottom:1px solid #FFFFFF;'";
									$tmp_style1_0 = "style='float:left; background-color:".$tmparr7[3]."; border-bottom:1px solid #FFFFFF;'";
									$tmp_style1_1 = "style='padding:5px 0 0 5px; background-color:".$tmparr7[3]."; border:medium double  #FFFFFF;'";
									$tmp_style2 = "style='background-color:".$tmparr7[3].";'";
								}

								//시간+일정제목
								if ($ind_image_diary == "Y" && !empty($tmparr7[10])){ // 액자없음
								echo "<li ".$tmp_style1_0."><a ".$tmp_style2." href=".$tmparr7[1]." title='".$tmparr7[2]."'><img style='vertical-align:top; float:left;' src='".$tmparr7[10]."'/>".$tmparr7[0].$tmparr7[9]."</a></li>";
								} else if ($ind_image_diary == "F" && !empty($tmparr7[10])){ // 액자있음
								echo "<li ".$tmp_style1_1."><a ".$tmp_style2." href=".$tmparr7[1]." title='".$tmparr7[2]."'><img style='vertical-align:top; float:left;' src='".$tmparr7[10]."'/><div style='clear:both;'>".$tmparr7[0].$tmparr7[9]."</div></a></li>";
								}
								else { 
			                    echo "<li ".$tmp_style.">".$lplan_state."<a ".$tmp_style2." href=".$tmparr7[1]." title='".$time_disply_fld.$tmparr7[2]."'>".trim($tmp_time[0])." ".$tmparr7[0].$tmparr7[9]."</a></li>"; 
								}
                             }
                        }   // end foreeach
                   }

                    // 셋째줄 --기념일---
                   if (!empty($tmparr5[0]) && $ind_memday == 'Y') { // 기념일만 체크
                        echo "<li><span class='memorial'>".$tmparr5[0]."</span></li>"; // 기념일
                   }
                 }
                echo ("</ul>");
                echo ("</td>\n");
            }
            echo ("</tr>\n");
        }
        ?>

        </tbody>
    </table>
<!--@if($display_offset != $offset && $offset != null && $device != printer )-->
	Server time is <font color='blue'>{date("l, F j, Y, g:i a", $display_timestamp)}</font>
	and your time is <font color='blue'>{date("l, F j, Y, g:i a", $client_timestamp)}</font> : {($display_timestamp-$client_timestamp)*(-1)/3600}Hrs difference.
<!--@end-->
</div>

<!--// 관리자로 로그인 했을경우 리스트 출력 -->
<!--@if($grant->manager)-->
	<!--@if($module_info->display_doc_list != "N")-->
		<!--#include("./_style.list_planner.html")-->
	<!--@endif-->
<!--@else-->
	{@$write_ymd = date('Y',$wrk_timestamp)."-".date('m',$wrk_timestamp)."-".date('d',$wrk_timestamp)}
    <div class="buttonRight" style="float:right;">
        <a href="{getUrl('act','dispBoardWrite','document_srl','','extra_vars1',$write_ymd)}" class="buttonOfficial"><span>{$lang->cmd_write}</span></a>
    </div>
<!--@end-->

<!--// 툴팁  XE V1.4.1.0에서 Qtip 문제 발생으로 아래를 주석 처리함 -->
<!--//%load_js_plugin("qtip")-->
<!--//
<script type="text/javascript">//<![CDATA[
var $j = jQuery.noConflict();
$j(document).ready(function()
{
    // qtip
    $j('a[title]').qtip({
      position: {
         corner: {        //bottomLeft, bottomRight, bottomMiddle, topRight, topLeft, topMiddle,
                        //leftMiddle, leftTop, leftBottom, rightMiddle, rightBottom, rightTop
            target: 'topMiddle',                                  
            tooltip: 'bottomMiddle'
         }
      },
      style: {
         name: 'green', //defaults,cream,light,dark,red,green,blue
         padding: '7px 13px',
         width: {
            max: 250,
            min: 0
         },
      border: {
         width:  3,  //border 굵기 지정
         radius: 0   //coner round 반경 지정(색을 지정하려면 끝에 "0,"처럼 끝에,를 붙일것)
         //color: '#A9DB66' //border color
         },
         tip: true
      }
    });
});
//]]></script>
-->