// Based on 「旧暦計算サンプルプログラム」 // Copyright (C) 1993,1994 by H.Takano // http://www.vector.co.jp/soft/dos/personal/se016093.html // // 本プログラムはフリーソフトです。 // 自由に再利用・改良を行ってかまいませんが、 // 改良された計算結果には責任が持てません。 // なお,本プログラムの原著作権は // 原典のjgAWK版を開発された高野英明氏に帰属しています。 // 上記のリンクより高野氏の「QRSAMP」を取得し、 // そのドキュメント内に書かれている再配布規定に従ってください。 // // C言語版に関しては,二次著作物としての取扱いになりますが、 // 上記、高野英明氏の再配布規定に従う限り,再配布は可能です。 //--------------------------------------------------------------- // 旧暦の2017年問題で, 新月になる旧暦2017年2月1日は // 新暦2月26日23時58分ですが,これを2月26日とするか27日にするか // という問題があり,本プログラムでは2月27日となります。 // // もし,新暦2017年2月26日を旧暦2017年2月1日とみなす場合, // 求められた日付を以下のようにずらす必要があります。 // //    1/30→2/1, 2/1〜2/29 →2/2〜2/30 //------------------------------------------------------------------ // C版 旧暦計算プログラム by 白井豊(Converted in 2017.08.25) // // getOldDate(西暦年,月,日); // // を実行すると、oldDate[0] 旧暦年 // oldDate[1] 閏月フラグ( 0 のとき平月, 1 のとき閏月) // oldDate[2] 旧暦月 // oldDate[3] 旧暦日 // が設定される。 // #include "stdio.h" #include "math.h" #include "string.h" #define PI 3.1415926535897932385 static double tm; //ユリウス日 static double chu[4][2]; //中気の時刻 static double nibun[4][2]; //二分二至の時刻、その時の黄経を配列で渡す static double saku[6]; //朔の時刻 static int oldDate[4]; //旧暦の格納配列 static int TIME[6]; //ユリウス日から計算された年月日、時分秒(世界時) //COS_Degree関数 static double cosD(double deg){return cos(deg*PI/180.0);} //========================================================================= // 角度の正規化。すなわち引数の範囲を 0≦θ<360 にする。 //========================================================================= static double N_ANGLE(double angle){ double angle1=0; double angle2=0; if( angle < 0.0 ){ angle1 = -angle; angle2 = (int)( angle1 / 360.0 ); angle1 -= 360.0 * angle2; angle1 = 360.0 - angle1; } else { angle1 = (int)( angle / 360.0 ); angle1 = angle - 360.0 * angle1; } return angle1; } //========================================================================= // 太陽の黄経 λsun を計算する //(原本では代入文が並んでいますが,これをテーブル化して行数を短くしました) //========================================================================= static double SunTab[][3]={ {0.0004, 31557.0, 161.0}, {0.0004, 29930.0, 48.0}, {0.0005, 2281.0, 221.0}, {0.0005, 155.0, 118.0}, {0.0006, 33718.0, 316.0}, {0.0007, 9038.0, 64.0}, {0.0007, 3035.0, 110.0}, {0.0007, 65929.0, 45.0}, {0.0013, 22519.0, 352.0}, {0.0015, 45038.0, 254.0}, {0.0018, 445267.0, 208.0}, {0.0018, 19.0, 159.0}, {0.0020, 32964.0, 158.0}, {0.0200, 71998.1, 265.1}}; static double L_SUN(double t){ //----------------------------------------------------------------------- // 摂動項の計算 //----------------------------------------------------------------------- double ang,th=0; for(int i=0;i<14;i++) th += SunTab[i][0]* cosD( N_ANGLE( SunTab[i][1]* t + SunTab[i][2])); ang = N_ANGLE( 35999.05 * t + 267.52 ); th -= 0.0048 * t * cosD(ang) ; th += 1.9147 * cosD(ang) ; //----------------------------------------------------------------------- // 比例項の計算 //----------------------------------------------------------------------- ang = N_ANGLE( 36000.7695 * t ); ang = N_ANGLE( ang + 280.4659 ); th = N_ANGLE( th + ang ); return th; } //========================================================================= // 月の黄経 λmoon を計算する //(原本では代入文が並んでいますが,これをテーブル化して行数を短くしました) //========================================================================= static double MoonTab[][3]={ {0.0003 , 2322131.0 , 191.0}, {0.0003 , 4067.0 , 70.0}, // 1 {0.0003 , 549197.0 , 220.0}, {0.0003 , 1808933.0 , 58.0}, // 3 {0.0003 , 349472.0 , 337.0}, {0.0003 , 381404.0 , 354.0}, // 5 {0.0003 , 958465.0 , 340.0}, {0.0004 , 12006.0 , 187.0}, // 7 {0.0004 , 39871.0 , 223.0}, {0.0005 , 509131.0 , 242.0}, // 9 {0.0005 , 1745069.0 , 24.0}, {0.0005 , 1908795.0 , 90.0}, //11 {0.0006 , 2258267.0 , 156.0}, {0.0006 , 111869.0 , 38.0}, //13 {0.0007 , 27864.0 , 127.0}, {0.0007 , 485333.0 , 186.0}, //15 {0.0007 , 405201.0 , 50.0}, {0.0007 , 790672.0 , 114.0}, //17 {0.0008 , 1403732.0 , 98.0}, {0.0009 , 858602.0 , 129.0}, //19 {0.0011 , 1920802.0 , 186.0}, {0.0012 , 1267871.0 , 249.0}, //21 {0.0016 , 1856938.0 , 152.0}, {0.0018 , 401329.0 , 274.0}, //23 {0.0021 , 341337.0 , 16.0}, {0.0021 , 71998.0 , 85.0}, //25 {0.0021 , 990397.0 , 357.0}, {0.0022 , 818536.0 , 151.0}, //27 {0.0023 , 922466.0 , 163.0}, {0.0024 , 99863.0 , 122.0}, //29 {0.0026 , 1379739.0 , 17.0}, {0.0027 , 918399.0 , 182.0}, //31 {0.0028 , 1934.0 , 145.0}, {0.0037 , 541062.0 , 259.0}, //33 {0.0038 , 1781068.0 , 21.0}, {0.0040 , 133.0 , 29.0}, //35 {0.0040 , 1844932.0 , 56.0}, {0.0040 , 1331734.0 , 283.0}, //37 {0.0050 , 481266.0 , 205.0}, {0.0052 , 31932.0 , 107.0}, //39 {0.0068 , 926533.0 , 323.0}, {0.0079 , 449334.0 , 188.0}, //41 {0.0085 , 826671.0 , 111.0}, {0.0100 , 1431597.0 , 315.0}, //43 {0.0107 , 1303870.0 , 246.0}, {0.0110 , 489205.0 , 142.0}, //45 {0.0125 , 1443603.0 , 52.0}, {0.0154 , 75870.0 , 41.0}, //47 {0.0304 , 513197.9 , 222.5}, {0.0347 , 445267.1 , 27.9}, //49 {0.0409 , 441199.8 , 47.4}, {0.0458 , 854535.2 , 148.2}, //51 {0.0533 , 1367733.1 , 280.7}, {0.0571 , 377336.3 , 13.2}, //53 {0.0588 , 63863.5 , 124.2}, {0.1144 , 966404.0 , 276.5}, //55 {0.1851 , 35999.05, 87.53},{0.2136 , 954397.74, 179.93}, //57 {0.6583 , 890534.22, 145.7}, {1.2740 , 413335.35, 10.74}, //59 {6.2888 , 477198.868, 44.963}};//60 static double L_MOON(double t){ //----------------------------------------------------------------------- // 摂動項の計算 //----------------------------------------------------------------------- double ang,th=0; for(int i=0;i<61;i++) th += MoonTab[i][0]* cosD( N_ANGLE(MoonTab[i][1]* t +MoonTab[i][2])); //----------------------------------------------------------------------- // 比例項の計算 //----------------------------------------------------------------------- ang = N_ANGLE( 481267.8809 * t ); ang = N_ANGLE( ang + 218.3162 ); th = N_ANGLE( th + ang ); return th; } //========================================================================= // 年月日、時分秒(世界時)からユリウス日(JD)を計算する // // ※ この関数では、グレゴリオ暦法による年月日から求めるものである。 // (ユリウス暦法による年月日から求める場合には使用できない。) //========================================================================= static double YMDT2JD(int year,int month,int day,int hour,int min,int sec){ if( month < 3.0 ){ year -= 1; month += 12; } int jd = (int)( 365.25 * year ); jd += (int)( year / 400.0 ); jd -= (int)( year / 100.0 ); jd += (int)( 30.59 * ( month-2.0 ) ); jd += 1721088; jd += day; double t = sec / 3600.0; t += min /60.0; t += hour; t /= 24.0; jd +=(int) t; return( jd ); } //========================================================================= // ユリウス日(JD)から年月日、時分秒(世界時)を計算する // // 戻り値の配列TIME[]の内訳 // TIME[0] ... 年 TIME[1] ... 月 TIME[2] ... 日 // TIME[3] ... 時 TIME[4] ... 分 TIME[5] ... 秒 // // ※ この関数で求めた年月日は、グレゴリオ暦法によって表されている。 // //========================================================================= static void JD2YMDT(double JD){ double tm; int x0 = (int)( JD+68570.0); int x1 = (int)( x0/36524.25 ); int x2 = x0 - (int)( 36524.25*x1 + 0.75 ); int x3 = (int)( ( x2+1 )/365.2425 ); int x4 = (int)(x2 - (int)( 365.25*x3 )+31.0); int x5 = (int)( (int)(x4) / 30.59 ); int x6 = (int)( (int)(x5) / 11.0 ); TIME[2] = x4 - (int)( 30.59*x5 ); TIME[1] = x5 - 12*x6 + 2; TIME[0] = 100*( x1-49 ) + x3 + x6; // 2月30日の補正 if(TIME[1]==2 && TIME[2] > 28){ if(TIME[0] % 100 == 0 && TIME[0] % 400 == 0)TIME[2]=29; else if(TIME[0] % 4 ==0)TIME[2]=29; else TIME[2]=28; } tm=86400.0*( JD - (int)( JD ) ); TIME[3] = (int)( tm/3600.0 ); TIME[4] = (int)( (tm - 3600.0*TIME[3])/60.0 ); TIME[5] = (int)( tm - 3600.0*TIME[3] - 60*TIME[4] ); } //========================================================================= // 朔時刻の計算 // 与えられた時刻の直近の朔の時刻(JST)を求める // // 呼び出し時にセットする変数 // tm ........ 計算対象となる時刻(ユリウス日) // 戻り値 .... 朔の時刻 // // ※ 引数、戻り値ともユリウス日で表し、時分秒は日の小数で表す。 // //========================================================================= static double calc_saku(double tm){ //----------------------------------------------------------------------- // ループカウンタのセット //----------------------------------------------------------------------- int lc=1; //----------------------------------------------------------------------- //時刻を分解する //----------------------------------------------------------------------- double tm1 = (int)( tm ), tm2 = tm - tm1; //----------------------------------------------------------------------- // JST ==> DT (補正時刻=0.0sec と仮定して計算) //----------------------------------------------------------------------- tm2-=9.0/24.0; //----------------------------------------------------------------------- // 繰り返し計算によって朔の時刻を計算する // (誤差が±1.0 sec以内になったら打ち切る。) //----------------------------------------------------------------------- double delta_t1=0,delta_t2=0; for(delta_t2 = 1.0 ; abs( delta_t1+delta_t2 ) > ( 1.0 / 86400.0 ) ; lc++){ //----------------------------------------------------------------------- // 太陽の黄経λsun ,月の黄経λmoon を計算 // t = (tm - 2451548.0 + 0.5)/36525.0; //----------------------------------------------------------------------- double t=(tm2+0.5) / 36525.0; t+= (tm1-2451545.0) / 36525.0; double rm_sun=L_SUN( t ); double rm_moon=L_MOON( t ); //----------------------------------------------------------------------- // 月と太陽の黄経差Δλ // Δλ=λmoon−λsun //----------------------------------------------------------------------- double delta_rm = rm_moon - rm_sun ; //----------------------------------------------------------------------- // ループの1回目(lc=1)で delta_rm < 0.0 の場合には引き込み範囲に // 入るように補正する //----------------------------------------------------------------------- if( lc==1 && delta_rm < 0.0 )delta_rm = N_ANGLE( delta_rm ); //----------------------------------------------------------------------- // 春分の近くで朔がある場合(0 ≦λsun≦ 20)で、月の黄経λmoon≧300 の // 場合には、Δλ= 360.0 − Δλ と計算して補正する //----------------------------------------------------------------------- else if( rm_sun >= 0 && rm_sun <= 20 && rm_moon >= 300 ){ delta_rm = N_ANGLE( delta_rm ); delta_rm = 360.0 - delta_rm; } //----------------------------------------------------------------------- // Δλの引き込み範囲(±40°)を逸脱した場合には、補正を行う //----------------------------------------------------------------------- else if( abs( delta_rm ) > 40.0 ) delta_rm = N_ANGLE( delta_rm ); //----------------------------------------------------------------------- // 時刻引数の補正値 Δt // delta_t = delta_rm * 29.530589 / 360.0; //----------------------------------------------------------------------- delta_t1 = (int)(delta_rm * 29.530589 / 360.0); delta_t2 = delta_rm * 29.530589 / 360.0; delta_t2 -= delta_t1; //----------------------------------------------------------------------- // 時刻引数の補正 // tm -= delta_t; //----------------------------------------------------------------------- tm1 = tm1 - delta_t1; tm2 = tm2 - delta_t2; if(tm2 < 0.0){tm2+=1.0;tm1-=1.0;} //----------------------------------------------------------------------- // ループ回数が15回になったら、初期値 tm を tm-26 とする。 //----------------------------------------------------------------------- if(lc == 15 && abs( delta_t1+delta_t2 ) > ( 1.0 / 86400.0 ) ){ tm1 = (int)( tm-26 ); tm2 = 0; } //----------------------------------------------------------------------- // 初期値を補正したにも関わらず、振動を続ける場合には初期値を答えとして // 返して強制的にループを抜け出して異常終了させる。 //----------------------------------------------------------------------- else if( lc > 30 && abs( delta_t1+delta_t2 ) > ( 1.0 / 86400.0 ) ){ tm1=tm;tm2=0; break; } } //----------------------------------------------------------------------- // 時刻引数を合成し、DT ==> JST 変換を行う // (補正時刻=0.0sec と仮定して計算) //----------------------------------------------------------------------- return tm2+tm1+9.0/24.0; } //========================================================================= // 直前の二分二至の時刻を求める // // 呼び出し時にセットする変数 // tm ........ 計算対象となる時刻(ユリウス日) // nibun ..... 戻り値を格納する配列のポインター // 戻り値 .... 二分二至の時刻、その時の黄経を配列nibun[]で渡す // //========================================================================= static void before_nibun(double tm){ //----------------------------------------------------------------------- //時刻引数を分解する //----------------------------------------------------------------------- double tm1 = (int)( tm ); double tm2 = tm - tm1; //----------------------------------------------------------------------- // JST ==> DT (補正時刻=0.0sec と仮定して計算) //----------------------------------------------------------------------- tm2-=9.0/24.0; //----------------------------------------------------------------------- // 直前の二分二至の黄経 λsun0 を求める //----------------------------------------------------------------------- double t=(tm2+0.5) / 36525.0; t+= (tm1-2451545.0) / 36525.0; double rm_sun=L_SUN( t ); double rm_sun0=90*(int)(rm_sun/90.0); //----------------------------------------------------------------------- // 繰り返し計算によって直前の二分二至の時刻を計算する // (誤差が±1.0 sec以内になったら打ち切る。) //----------------------------------------------------------------------- double delta_t1=0,delta_t2=0; for( delta_t2 = 1.0 ; abs( delta_t1+delta_t2 ) > ( 1.0 / 86400.0 ) ; ){ //----------------------------------------------------------------------- // λsun を計算 //----------------------------------------------------------------------- t=(tm2+0.5) / 36525.0; t+= (tm1-2451545.0) / 36525.0; rm_sun=L_SUN( t ); //----------------------------------------------------------------------- // 黄経差 Δλ=λsun −λsun0 //----------------------------------------------------------------------- double delta_rm = rm_sun - rm_sun0 ; //----------------------------------------------------------------------- // Δλの引き込み範囲(±180°)を逸脱した場合には、補正を行う //----------------------------------------------------------------------- if( delta_rm > 180.0 )delta_rm-=360.0; else if( delta_rm < -180.0) delta_rm+=360.0; //----------------------------------------------------------------------- // 時刻引数の補正値 Δt // delta_t = delta_rm * 365.2 / 360.0; //----------------------------------------------------------------------- delta_t1 = (int)(delta_rm * 365.2 / 360.0); delta_t2 = delta_rm * 365.2 / 360.0; delta_t2 -= delta_t1; //----------------------------------------------------------------------- // 時刻引数の補正 // tm -= delta_t; //----------------------------------------------------------------------- tm1 = tm1 - delta_t1; tm2 = tm2 - delta_t2; if(tm2 < 0){tm2+=1.0;tm1-=1.0;} } //----------------------------------------------------------------------- // nibun[0,0]:時刻引数を合成し、DT ==> JST 変換を行う // (補正時刻=0.0sec と仮定して計算) // nibun[0,1]:黄経 //----------------------------------------------------------------------- nibun[0][0]=tm2+9.0/24.0; nibun[0][0]+=tm1; nibun[0][1]=rm_sun0; } //========================================================================= // 中気の時刻を求める // // 呼び出し時にセットする変数 // tm ........ 計算対象となる時刻(ユリウス日) // chu ....... 戻り値を格納する配列のポインター // i ......... 戻り値を格納する配列の要素番号 // 戻り値 .... 中気の時刻、その時の黄経を配列chu[]で渡す //========================================================================= static void calc_chu(double tm,int i){ //----------------------------------------------------------------------- //時刻引数を分解する //----------------------------------------------------------------------- double tm1 = (int)( tm ); double tm2 = tm - tm1; //----------------------------------------------------------------------- // JST ==> DT (補正時刻=0.0sec と仮定して計算) //----------------------------------------------------------------------- tm2-=9.0/24.0; //----------------------------------------------------------------------- // 中気の黄経 λsun0 を求める //----------------------------------------------------------------------- double t=(tm2+0.5) / 36525.0; t=t + (tm1-2451545.0) / 36525.0; double rm_sun=L_SUN( t ); double rm_sun0=30.0*(int)(rm_sun/30.0); //----------------------------------------------------------------------- // 繰り返し計算によって中気の時刻を計算する // (誤差が±1.0 sec以内になったら打ち切る。) //----------------------------------------------------------------------- double delta_t1=0,delta_t2=0; for( delta_t2 = 1.0 ; abs( delta_t1+delta_t2 ) > ( 1.0 / 86400.0 ) ; ){ //----------------------------------------------------------------------- // λsun を計算 //----------------------------------------------------------------------- t=(tm2+0.5) / 36525.0; t=t + (tm1-2451545.0) / 36525.0; rm_sun=L_SUN( t ); //----------------------------------------------------------------------- // 黄経差 Δλ=λsun −λsun0 //----------------------------------------------------------------------- double delta_rm = rm_sun - rm_sun0 ; //----------------------------------------------------------------------- // Δλの引き込み範囲(±180°)内に補正を行う //----------------------------------------------------------------------- if( delta_rm > 180.0 ) delta_rm-=360.0; else if( delta_rm < -180.0 )delta_rm+=360.0; //----------------------------------------------------------------------- // 時刻引数の補正値 Δt // delta_t = delta_rm * 365.2 / 360.0; //----------------------------------------------------------------------- delta_t1 = (int)(delta_rm * 365.2 / 360.0); delta_t2 = delta_rm * 365.2 / 360.0; delta_t2 -= delta_t1; //----------------------------------------------------------------------- // 時刻引数の補正 // tm -= delta_t; //----------------------------------------------------------------------- tm1 = tm1 - delta_t1; tm2 = tm2 - delta_t2; if(tm2 < 0){tm2 += 1.0; tm1 -= 1.0;} } //----------------------------------------------------------------------- // chu[i,0]:時刻引数を合成しDT ==> JST 変換を行う。 // (補正時刻=0.0sec と仮定して計算) // chu[i,1]:黄経 //----------------------------------------------------------------------- chu[i][0]=tm2+9.0/24.0; chu[i][0]+=tm1; chu[i][1]=rm_sun0; } //========================================================================= // 新暦に対応する、旧暦を求める。 // // 呼び出し時にセットする変数 // tm0 : 計算する日付(ユリウス日) // oldDate : 結果の格納先(配列に結果を返却する) // oldDate[0] : 旧暦年 // oldDate[1] : 平月/閏月 flag .... 平月:0 閏月:1 // oldDate[2] : 旧暦月 // oldDate[3] : 旧暦日 // // (注) 朔(さく, new moon)とは月と太陽の視黄経が等しくなること、 // またはその時刻のことです。現代的な定義での新月(しんげつ)とほぼ同義です。 // 伝統的な意味の「新月」は、本来「朔の後に初めて見える月」のことですので、 // 誤解を避けるため「朔」という言葉を使います。 //========================================================================= static void calc_oldDate(double tm0){ JD2YMDT(tm0); oldDate[0]=TIME[0]; oldDate[2]=TIME[1]; oldDate[3]=TIME[2]; //----------------------------------------------------------------------- // 計算対象の直前にあたる二分二至の時刻を求める // chu[0,0]:二分二至の時刻 chu[0,1]:その時の太陽黄経 //----------------------------------------------------------------------- before_nibun(tm0); chu[0][0]=nibun[0][0]; chu[0][1]=nibun[0][1]; //----------------------------------------------------------------------- // 中気の時刻を計算(4回計算する) // chu[i,0]:中気の時刻 chu[i,1]:太陽黄経 //----------------------------------------------------------------------- for(int i=1;i<4;i++) calc_chu(chu[i-1][0]+32.0,i); //----------------------------------------------------------------------- // 計算対象の直前にあたる二分二至の直前の朔の時刻を求める //----------------------------------------------------------------------- saku[0]=calc_saku(chu[0][0]); //----------------------------------------------------------------------- // 朔の時刻を求める //----------------------------------------------------------------------- for(int i=1;i<5;i++){ tm=saku[i-1];tm+=30.0; saku[i]=calc_saku(tm); // 前と同じ時刻を計算した場合(両者の差が26日以内)には、初期値を // +33日にして再実行させる。 if( abs( (int)(saku[i-1])-(int)(saku[i]) ) <= 26.0 ) saku[i]=calc_saku(saku[i-1]+35.0); } //----------------------------------------------------------------------- // saku[1]が二分二至の時刻以前になってしまった場合には、朔をさかのぼり過ぎ // たと考えて、朔の時刻を繰り下げて修正する。 // その際、計算もれ(saku[4])になっている部分を補うため、朔の時刻を計算 // する。(近日点通過の近辺で朔があると起こる事があるようだ...?) //----------------------------------------------------------------------- if( (int)(saku[1]) <= (int)(chu[0][0]) ){ for(int i=0;i<5;i++)saku[i]=saku[i+1]; saku[4]=calc_saku(saku[3]+35.0); } //----------------------------------------------------------------------- // saku[0]が二分二至の時刻以後になってしまった場合には、朔をさかのぼり足 // りないと見て、朔の時刻を繰り上げて修正する。 // その際、計算もれ(saku[0])になっている部分を補うため、朔の時刻を計算 // する。(春分点の近辺で朔があると起こる事があるようだ...?) //----------------------------------------------------------------------- else if( (int)(saku[0]) > (int)(chu[0][0]) ){ for(int i=4;i>0;i--)saku[i]=saku[i-1]; saku[0]=calc_saku(saku[0]-27.0); } //----------------------------------------------------------------------- // 閏月検索Flagセット // (節月で4ヶ月の間に朔が5回あると、閏月がある可能性がある。) // lap=0:平月 lap=1:閏月 //----------------------------------------------------------------------- int lap=0; if((int)(saku[4]) <= (int)(chu[3][0]) ) lap=1; //----------------------------------------------------------------------- // 朔日行列の作成 // m[i,0] ... 月名(1:正月 2:2月 3:3月 ....) // m[i,1] ... 閏フラグ(0:平月 1:閏月) // m[i,2] ... 朔日のjd //----------------------------------------------------------------------- int m[5][3]; m[0][0]=(int)(chu[0][1]/30.0) + 2; m[0][1]=lap; m[0][2]=(int)(saku[0]);m[0][1]=0; for(int i=1;i<5;i++){ if(lap==1 && i!=1 ){ if( (int)(chu[i-1][0]) <= (int)(saku[i-1]) || (int)(chu[i-1][0]) >= (int)(saku[i]) ){ m[i-1][0]=m[i-2][0];m[i-1][1]=1; m[i-1][2]=(int)(saku[i-1]); lap=0; } } m[i][0]=m[i-1][0]+1; if( m[i][0] > 12 ) m[i][0]-=12; m[i][2]=(int)(saku[i]);m[i][1]=0; } //----------------------------------------------------------------------- // 朔日行列から旧暦を求める。 //----------------------------------------------------------------------- int state=0,i; for(i=0;i<5;i++){ if((int)(tm0) < (int)(m[i][2])) {state=1;break;} else if((int)(tm0) == (int)(m[i][2])){state=2;break;} } if(state==0||state==1)i--; oldDate[1]=m[i][1]; oldDate[2]=m[i][0]; oldDate[3]=(int)(tm0)-(int)(m[i][2])+1; //----------------------------------------------------------------------- // 旧暦年の計算 // (旧暦月が10以上でかつ新暦月より大きい場合には、 // まだ年を越していないはず...) //----------------------------------------------------------------------- JD2YMDT(tm0); oldDate[0]=TIME[0]; if(oldDate[2] > 9 && oldDate[2] > TIME[1]) oldDate[0]--; } //========================================================================= // 旧暦日付を求める // // Y : 新暦西暦年 // M : 新暦月 // D : 新暦日 // 戻り値 : oldDateに旧暦日付データ //========================================================================= void getOldDate(int Y,int M, int D){ tm = YMDT2JD(Y,M,D,0,0,0); //ユリウス日を計算 calc_oldDate(tm); //ユリウス日から旧暦を求める } //========================================================================= // テスト用メイン //========================================================================= int main(void){ char ROKUYO[][7]={"先勝", "友引", "先負", "仏滅", "大安", "赤口"}; char lpStr[][6]={"","閏"}; int Y,M,D; printf("\n新暦を西暦年/月/日の形式で入力>>"); while(scanf("%d/%d/%d",&Y,&M,&D)!=EOF){ getOldDate(Y,M,D); printf("旧暦 %d/%s%02d/%02d %s\n",oldDate[0], lpStr[oldDate[1]], oldDate[2],oldDate[3], ROKUYO[(oldDate[2]+oldDate[3]-2)%6]); printf("\n新暦を西暦年/月/日の形式で入力>>"); } return 0; }