機能|太陰暦
コード: - - - - - - - - - - - - - - - - - - - - - - - - --------------------------------
[この記事の全文] [この記事への返信] [この記事の執筆者]記事: トップ ] [ この記事の人気: 10 ]
送信者: トップ (CET-6&&PHP)、エリア: プログラミング
タイトル: 太陰太陽暦アルゴリズム
送信ステーション: 延照 BBS (火 4 月 8 日 12:14:16 2003)、転送
http://linux.tcpip.com.cn
太陰太陽アルゴリズム
スピーカー: kent 発言時間: 2001-11-08 12:03:11
プログラムは:
/*
プロトタイプ: intconv cal ( struct convdate * );
struct convdate
{
int source; ==0 は入力日付が西暦であることを意味し、!=0 は入力が太陰暦であることを意味します
int 太陽年を出力します。または入力
int sunarmonth; 西暦の月
int lunaryear; 出力または入力の太陰月
int 太陰暦の月
int 曜日;今週の (0==日曜日、1== 月曜日、... )
int kan; その日の天幹 (0==A、1==B、...、9==縸)
int chih; その日の地上の枝 (0==Zi, 1== Ugly, ..., 11==Hai)
};
を呼び出すときは、source の値を設定する必要があります。西暦から旧暦への変換、それ以外の場合は旧暦から西暦への変換です。 そして、
入力を西暦または旧暦として扱います 西暦の年、月、日を設定します。変換された年、月、日が構造体(太陰暦または西暦)に埋め込まれます。また、関数の戻り値が 0 の場合は、それを意味します。エラーはありません。1 は入力された年が間違っていることを意味します。2 は入力された月が間違っていることを意味します
、
3 は入力された日付が間違っていることを意味します。
入力された西暦年は 1937 年から 2031 年の間である必要があります
入力された旧暦は次である必要がありますbetween 1936 - 2030
If 拡張が必要な場合は、lunarcal[]
*/
#define firstyear 1936 /* the first year in lunarcal[] */
struct convdate
{
int source;
int source;
int Solaryear;
int Solarmonth;
int Solardate;
int Lunaryear;
int Lunarmonth;
int Lunardate;
int Weekday;
int kan;
int chih;
};
struct taglunarcal
{
int Basedays / * 1 月 1 日まで 旧暦の最初の日までの累積日数*/
int intercalation; /* 閏月 0==今年には閏月はありません*/
int baseweekday;今年の西暦は曜日から 1 を引いたものです */
intbasekanchih /* 今年の 1 月 1 日の幹と枝の数を 1 つ減らします */
int monthdays[13]; /* のサイズこの旧暦の各月、0==小月 (29 日)、1== 大月 (30 日
)*/
};
struct taglunarcal lunarcal[] = {
{ 23, 3, 2, 17, 1 , 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 }, /* 1936 */
{ 23, 3, 2, 17, 1, 0, 0, 1, 0 , 0, 1, 1, 0, 1, 1, 1, 0 }, / * 1936 */
{ 41, 0, 4, 23, 1, 0, 0, 1, 0, 0, 1, 0, 1 , 1, 1, 0, 1 },
{ 30, 7, 5, 28 , 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 },
{ 49 , 0, 6, 33, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 38, 0, 0, 38, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, /* 1940 */
{ 26, 6, 2, 44, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 45, 0, 3, 49, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 35, 0, 4, 54, 0, 1, 0, 1, 0 , 1, 1, 0, 1, 0, 1, 0, 1 },
{ 24, 4, 5, 59, 1, 0 , 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 1944 */
{ 43, 0, 0, 5, 0, 0, 1, 0, 0, 1 , 0, 1, 1, 1, 0, 1, 1 },
{ 32 , 0, 1, 10, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 },
{ 21, 2, 2, 15, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 40, 0, 3, 20, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 , 0, 1, 1 }, /* 1948 */
{ 28, 7, 5, 26, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 47, 0, 6, 31, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1 , 0, 1 },
{ 36, 0, 0, 36, 1, 0 , 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 26, 5, 1 , 41, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 }, /* 1952 */
{ 44, 0, 3, 47, 0, 1, 0 , 0, 1, 1, 0, 1, 1, 0, 1, 0, 1 },
{ 33, 0, 4, 52, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 },
{ 23, 3, 5, 57, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },
{ 42, 0, 6, 2, 0, 1, 0, 1, 0, 0, 1 , 0, 1, 0, 1, 1, 1 }, /* 1956 */
{ 30, 8, 1, 8, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 , 1, 0 },
{ 48, 0, 2, 13, 1, 1, 1, 0, 1, 0, 0, 1 , 0, 1, 0, 1, 0 },
{ 48, 0, 2 , 13, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
{ 38, 0, 3, 18, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
{ 27, 6, 4, 23, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 , 0 }, /* 1960 */
{ 45, 0, 6, 29, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 },
{ 35, 0, 0, 34, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 24, 4, 1, 39, 1, 0, 1, 0 , 0, 1, 0, 1, 0, 1, 1, 1, 0 },
{ 43, 0, 2, 44, 1 , 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 }, /* 1964 */
{ 32, 0, 4, 50, 0, 1, 0, 1, 0 , 0, 1, 0, 0, 1, 1, 0, 1 },
{ 20, 3, 5, 55, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },
{ 39, 0, 6, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
{ 29, 7, 0, 5, 0, 1, 0, 1, 1, 0, 1, 0, 1 , 0, 1, 0, 1 }, /* 1968 */
{ 47, 0, 2, 11, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 36, 0, 3, 16, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 , 0, 1, 0 },
{ 26, 5, 4, 21, 0 , 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1 },
{ 45, 0 , 5, 26, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 1972 */
{ 33, 0, 0, 32, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1 },
{ 22, 4, 1, 37, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
{ 41, 0, 2, 42, 1, 1, 0, 1, 0, 0, 1, 0, 0 , 1, 0, 1, 1 },
{ 30, 8, 3, 47, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }, /* 1976 */
{ 48, 0, 5, 53, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1 },
{ 37, 0, 6, 58, 1 , 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 27, 6, 0, 3, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 },
{ 46, 0, 1, 8, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 1980 */
{ 46, 0, 1, 8, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 1980 */
{ 35 , 0, 3, 14, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 },
{ 24, 4, 4, 19, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
{ 43, 0, 5, 24, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0 , 1, 1, 1 },
{ 32, 10, 6, 29, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 }, /* 1984 */
{ 50, 0, 1, 35, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 39, 0, 2, 40, 0, 1 , 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1 },
{ 28, 6, 3, 45, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0 },
{ 47, 0, 4, 50, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, /* 1988 */
{ 36, 0, 6, 56, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 },
{ 26, 5, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1 },
{ 45, 0, 1, 6, 0, 1, 0, 0, 1, 0, 0 , 1, 0, 1, 1, 1, 0 },
{ 34, 0, 2, 11, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0 } , /* 1992 */
{ 22, 3, 4, 17, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 40, 0, 5 , 22, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 30, 8, 6, 27, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1 },
{ 49, 0, 0, 32, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0 , 1 }, /* 1996 */
{ 37, 0, 2, 38, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 27, 5, 3, 43, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 46, 0, 4, 48, 1, 0, 0, 1 , 0, 0, 1, 0, 1, 1, 1, 0, 1 },
{ 35, 0, 5, 53, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 }, /* 2000 */
{ 23, 4, 0, 59, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 42, 0, 1, 4, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 42, 0, 1, 4, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 31, 0, 2, 9, 1, 1, 0, 1, 1, 0, 1, 0, 0 , 1, 0, 1, 0 },
{ 21, 2, 3, 14, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, /* 2004 */
{ 39, 0, 5, 20, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 28, 7, 6, 25, 1 , 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 },
{ 48, 0, 0, 30, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 },
{ 37, 0, 1, 35, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 2008 */
{ 25, 5, 3, 41, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 44, 0, 4, 46, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 33, 0, 5, 51, 1, 0, 1, 1, 0, 1 , 0, 0, 1, 0, 1, 0, 1 },
{ 22, 4, 6, 56, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, /* 2012 */
{ 40, 0, 1, 2, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 30, 9 , 2, 7, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },
{ 49, 0, 3, 12, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 },
{ 38, 0, 4, 17, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 , 1, 0 }, /* 2016 */
{ 27, 6, 6, 23, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },
{ 46, 0, 0, 28, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0 },
{ 35, 0, 1, 33, 0, 1, 1 , 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },
{ 24, 4, 2, 38, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, /* 2020 */
{ 42, 0, 4, 44, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 } ,
{ 31, 0, 5, 49, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 21, 2, 6, 54, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },
{ 40, 0, 0, 59, 0, 1, 0, 0, 1, 0, 1, 1 , 0, 1, 1, 0, 1 }, /* 2024 */
{ 40, 0, 0, 59, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 , 1 }, /* 2024 */
{ 28, 6, 2, 5, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },
{ 47, 0, 3, 10, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1 },
{ 36, 0, 4, 15, 1, 1, 0, 1 , 0, 0, 1, 0, 0, 1, 1, 0, 1 },
{ 25, 5, 5, 20, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 }, /* 2028 */
{ 43, 0, 0, 26, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 },
{ 32, 0, 1, 31, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
{ 22, 3, 2, 36, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 } };
#define lastyear (firstyear+sizeof(lunarcal)/sizeof(struct
taglunarcal)-1)
/*西历年每月之毎日 */
int Solarcal[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
/* 西历年每月之累積日数, 平年与闰年 */
int sundays[2][14] = {
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 396 },
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 397 } };
/* 求此西历年が闰年であるかどうか、戻り値 0 は平年、1である年 */
int getleap( int year )
{
if ( year % 400 == 0 )
if ( year % 400 == 0 )
return 1;
else if ( year % 100 == 0 )
return 0;
else if ( year % 4 == 0 )
return 1;
else
return 0;
}
/* 西历农历转换 */
int calconv( struct convdate *cd )
{
int Leap, d , sm, y, im, l1, l2, acc, i, lm, kc;
if ( cd->source == 0 ) /* 太陽 */
{
if ( cd->solaryear <= firstyear || cd->太陽年>去年)
return 1;
sm = cd->solarmonth - 1;
if ( sm < 0 || sm > 11 )
return 2;
leap = getleap( cd->solaryear );
if ( sm == 1 )
if ( sm == 1 )
d = リープ + 28;
else
d = Solarcal[sm];
if ( cd->solardate < 1 || cd->solardate > d )
return 3;
y = cd->solaryear - firstyear;
acc = Solardays[leap][sm] + cd->solardate;
cd->weekday = ( acc + lunarcal[y].baseweekday ) % 7;
kc = acc + lunarcal[y].basekanchih;
cd->kan = kc % 10;
cd->chih = kc % 12;
if ( acc <= lunarcal[y].baseays )
{
y- -;
cd->lunaryear = cd->solaryear - 1;
leap = getleap( cd->lunaryear );
sm += 12;
acc = Solardays[leap][sm] + cd-> Solardate;
}
else
cd->lunaryear = cd->solaryear;
l1 = lunarcal[y].basedays;
l1 = lunarcal[y].basedays;
for ( i=0; i<13; i++ )
{
l2 = l1 + lunarcal[y].monthdays[i] + 29;
if ( acc <= l2 )
break;
l1 = l2;
}
cd->lunarmonth = i + 1 ;
cd->lunardate = acc - l1;
im = lunarcal[y].intercalation;
if ( im != 0 && cd->lunarmonth > im )
{
cd->lunarmonth--;
if ( cd->lunarmonth == im )
cd->lunarmonth = -im;
}
if ( cd->lunarmonth > 12 )
cd->lunarmonth -= 12;
}
else /* lunar */
{
if ( cd->lunaryear < firstyear || cd->lunaryear >= lastyear )
if ( cd ->太陰年 < 初年 || cd->太陰年 >= 昨年 )
return 1;
y = cd->太陰年 - 初年;
im = lunarcal[y].intercalation;
lm = cd-> ;lunarmonth;
if ( lm {
if ( lm != -im )
return 2;
}
else if ( lm 12 )
return 2;
if ( im != 0 )
{
if ( lm > im )
lm++;
else if ( lm == -im )
lm = im + 1;
}
lm--;
if ( cd->lunardate > 月経[y].月日[lm] + 29 )
return 3;
acc = 月経[y].basedays;
acc = 月経[y].basedays;
for ( i=0; i acc += 月経[y].monthdays[i] + 29;
acc += cd->lunardate;
leap = getleap( cd->lunaryear );
for ( i=13; i>=0; i-- )
if ( acc > sundays[leap][i] )
break;
cd->solardate = acc - Solardays[leap][i];
if ( i {
cd->solaryear = cd->太陰年;
cd->太陽月 = i + 1;
}
else
{
cd->太陽年 = cd->太陰年 + 1;
cd->太陽月 = i - 11;
}
leap = getleap( cd->solaryear );
y = cd->solaryear - firstyear;
acc = Solardays[leap][cd->solarmonth-1] + cd->solardate;
cd ->曜日 = ( acc + lunarcal[y].baseweekday ) % 7;
kc = acc + lunarcal[y].basekanchih;
{
cd->kan = kc % 10;
cd->chih = kc % 12;
}
return 0;
}