打印

求一个计算24节气的c程序,给出计算公式也行,多谢。

[复制链接]
6431|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
WYF1228|  楼主 | 2008-11-9 23:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
李冬发| | 2008-11-9 23:54 | 只看该作者

节与气的时长为365.2422/24,剩下的自己算就是了

使用特权

评论回复
板凳
linqing171| | 2008-11-10 13:12 | 只看该作者

楼上正解。

不过还有个口诀是这么说的:
上半年逢六二十一,下半年逢八二十三,日期一般不变更,有时也差一两天。

阳历的1月到6月的 初六和21 分别是节和气,
7月到12月的每月初八和23是对应的节气。

比如:春分为3月21,左右误差一天。

http://baike.baidu.com/view/10644.htm
  春分日期的计算 [Y*D+C]-L
  公式解读:年数的后2位乘0.2422加20.646取整数减闰年数。21世纪春分的C值=20.646。
  举例说明:2092年春分日期=[92×.0.2422+20.646]-[92/4]=42-23=19,3月19日是春分。
  例外:2084年的计算结果加1日。




但是由于节气是农历里面来的,所以节气的计算口诀计算出来的和实际的理论值还是略有差距。具体以万年历为准。

使用特权

评论回复
地板
guosr| | 2008-11-10 19:37 | 只看该作者

不是这么算的

    24节气并非在365.2425天上面平均分配,而是在地球公转轨道的椭圆周上按角度平均分配。当太阳垂直照射赤道时定为“黄经零度”,即春分点。从这里出发,每前进15度就为一个节气。
    地球公转轨道是一个椭圆,按照行星运动的开普勒定律,地球在近日点(冬至前后)的运动速度高,地球和太阳的连线扫过15度所需的时间短,因此这段时间两个节气之间的时间略短;在远日点(夏至前后),地球运动速度低,地球和太阳的连线扫过15度所需的时间长,因此这段时间两个节气之间的时间略长。
    因此,24节气之间的间隔并非是365.2425/24,楼上几位的公式是错的。

使用特权

评论回复
5
msliang18| | 2008-11-10 20:49 | 只看该作者

查表法吧

这是以前自己完ucos时弄的一个程序,就是浪费点空间;
因为不是做产品,所以也没有对代码效率考虑太多,楼主自己取舍。



/************************************************************************************************************/
/*阳历日和农历节气的对应关系                                                                                */
/*压缩节气数据表:                                                                                            */
/*根据规律可以得到四个数据表(每个阳历月有两个节气,每个节气需要两个数据表):                                */
/************************************************************************************************************/
INT8U calendar_solar_term_table_01[12][33] = 
{
    {7,6,6,6,6,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,4,5,5},             //month 1
    {5,4,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,3,4,4,4,3,3,4,4,3,3,3},             //2
    {6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},        //3
    {5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,4,4,5,5,4,4,4,5,4,4,4,4,5},         //4
    {6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},         //5
    {6,6,7,7,6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},//6
    {7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,6,6,6,7,7},         //7
    {8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,7},//8
    {8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,7},         //9
    {9,9,9,9,8,9,9,9,8,8,9,9,8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,8},         //10
    {8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,7},         //11
    {7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,6,6,6,7,7},         //12
}; //这个数据表表示了每个月第一个节气出现的规律

INT8U calendar_solar_term_year_01[12][9] = 
{
    {13,49,85,117,149,185,201,250,250}, //month 1
    {13,45,81,117,149,185,201,250,250}, //2
    {13,48,84,112,148,184,200,201,250}, //3
    {13,45,76,108,140,172,200,201,250}, //4
    {13,44,72,104,132,168,200,201,250}, //5
    {5 ,33,68,96 ,124,152,188,200,201}, //6
    {29,57,85,120,148,176,200,201,250}, //7
    {13,48,76,104,132,168,196,200,201}, //8
    {25,60,88,120,148,184,200,201,250}, //9
    {16,44,76,108,144,172,200,201,250}, //10
    {28,60,92,124,160,192,200,201,250}, //11
    {17,53,85,124,156,188,200,201,250}, //12
}; //这个数据表表示了每个月第一个节气出现规律对应的阳历年份范围

INT8U calendar_solar_term_table_02[12][29] = 
{
    {21,21,21,21,21,20,21,21,21,20,20,21,21,20,20,20,20,20,20,20,20,19,20,20,20,19,19,20},
    {20,19,19,20,20,19,19,19,19,19,19,19,19,18,19,19,19,18,18,19,19,18,18,18,18,18,18,18},
    {21,21,21,22,21,21,21,21,20,21,21,21,20,20,21,21,20,20,20,21,20,20,20,20,19,20,20,20,20},
    {20,21,21,21,20,20,21,21,20,20,20,21,20,20,20,20,19,20,20,20,19,19,20,20,19,19,19,20,20},
    {21,22,22,22,21,21,22,22,21,21,21,22,21,21,21,21,20,21,21,21,20,20,21,21,20,20,20,21,21},
    {22,22,22,22,21,22,22,22,21,21,22,22,21,21,21,22,21,21,21,21,20,21,21,21,20,20,21,21,21},
    {23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,23,23,22,22,22,23,22,22,22,22,23},
    {23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,23,23,22,22,22,23,23},
    {23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,23,23,22,22,22,23,23},
    {24,24,24,24,23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,23,23,23},
    {23,23,23,23,22,23,23,23,22,22,23,23,22,22,22,23,22,22,22,22,21,22,22,22,21,21,22,22,22},
    {22,22,23,23,22,22,22,23,22,22,22,22,21,22,22,22,21,21,22,22,21,21,21,22,21,21,21,21,22},

}; //这个数据表表示了每个月第二个节气出现的规律

INT8U calendar_solar_term_year_02[12][8] = 
{
    {13,45,81,113,149,185,201},
    {21,57,93,125,161,193,201},
    {21,56,88,120,152,188,200,201},
    {21,49,81,116,144,176,200,201},
    {17,49,77,112,140,168,200,201},
    {28,60,88,116,148,180,200,201},
    {25,53,84,112,144,172,200,201},
    {29,57,89,120,148,180,200,201},
    {17,45,73,108,140,168,200,201},
    {28,60,92,124,160,192,200,201},
    {16,44,80,112,148,180,200,201},
    {17,53,88,120,156,188,200,201},
};//这个数据表表示了每个月第二个节气出现规律对应的阳历年份范围


/************************************************************************************************************/
/*函    数:calendar_calculate_solar_term_1                                                                    */
/*输    入:solar_year,solar_month                                                                              */
/*输    出:第一个节气出现的日期;                                                                               */
/*函数说明:本函数用于计算给定年和月的第一个农历节日出现的节气,输入的年按-1900给定                              */
/*         这个算法采用条件规律算法.给定的年和月信息是阳历,返回的日期也为阳历                                */
/************************************************************************************************************/
INT8U calendar_calculate_solar_term_1(INT8U solar_year, INT8U solar_month)
{
    INT8U done_index;
    INT8U solar_term;
    
    done_index = 0;
    
    while(solar_year >= calendar_solar_term_year_01[solar_month - 1][done_index])
    {
        done_index++;
        if(done_index>8) break;                    //以防设置的年不在数据表格范围内;
    }
    solar_term = calendar_solar_term_table_01[solar_month - 1][4*done_index + solar_year%4];
    
    if((solar_year == 121)&&(solar_month == 4))solar_term = 5;
    if((solar_year == 132)&&(solar_month == 4))solar_term = 5;
    if((solar_year == 194)&&(solar_month == 6))solar_term = 6;
    return(solar_term);
}

/************************************************************************************************************/
/*函    数:calendar_calculate_solar_term_2                                                                    */
/*输    入:solar_year,solar_month                                                                              */
/*输    出:第二个节气出现的日期;                                                                               */
/*函数说明:本函数用于计算给定年和月的第二个农历节日出现的节气,输入的年按-1900给定                              */
/*         这个算法采用条件规律算法.给定的年和月信息是阳历,返回的日期也为阳历                                */
/************************************************************************************************************/
INT8U calendar_calculate_solar_term_2(INT8U solar_year, INT8U solar_month)
{
    INT8U done_index;
    INT8U solar_term;
    
    done_index = 0;
    
    while(solar_year >= calendar_solar_term_year_02[solar_month - 1][done_index])
    {
        done_index++;
        if(done_index>8) break;                    //以防设置的年不在数据表格范围内;
    }
    solar_term = calendar_solar_term_table_02[solar_month - 1][4*done_index + solar_year%4];
    
    if((solar_year == 171)&&(solar_month == 3))solar_term = 21;
    if((solar_year == 181)&&(solar_month == 5))solar_term = 21;
    return(solar_term);
}

使用特权

评论回复
6
msliang18| | 2008-11-10 20:53 | 只看该作者

声明一下

以上代码非本人原创,至于出处,隔离较长时间,记不起来了。

使用特权

评论回复
7
linqing171| | 2008-11-11 14:57 | 只看该作者

开普勒第几定律有用?

1、近地点和远地点的具体差距为平均距离的偏差2%以内。
2、根据开普勒第三定律,地球单位时间扫过的扇区是等面积的,所以角度乘以R的平方是常数,推出地球角速度最大变化小于 4%以内。
3、平均计算的算法,冬至和夏至是准的,春秋分一个超前到最大,一个滞后到最大。

经过以上的基本知识,可以推测出最大偏差90*4%=3.6天。理论实际值应该是1到两天。

楼上的应该是 《万年历》 《周易》 《奇门遁甲》 等历法的书里面的公式搞出来的表吧,不过确实压缩后看不懂了。

2000年 1月 3日 13时 近日点 日心距au= .983321418
2000年 7月 4日   8时 远日点 日心距au= 1.016741091
2001年 1月 4日 17时 近日点 日心距au= .983286028
2001年 7月 4日 22时 远日点 日心距au= 1.016642627
2002年 1月 2日 22时 近日点 日心距au= .983289783
2002年 7月 6日 12时 远日点 日心距au= 1.016688203
2003年 1月 4日 13时 近日点 日心距au= .983320381
2003年 7月 4日 14时 远日点 日心距au= 1.016728230
2004年 1月 5日   2时 近日点 日心距au= .983264836
2004年 7月 5日 19时 远日点 日心距au= 1.016693679
2005年 1月 2日   9时 近日点 日心距au= .983296823
2005年 7月 5日 13时 远日点 日心距au= 1.016741599
2006年 1月 4日 23时 近日点 日心距au= .983326979
2006年 7月 4日   7时 远日点 日心距au= 1.016697260
2007年 1月 4日   4时 近日点 日心距au= .983260183
2007年 7月 7日   8时 远日点 日心距au= 1.016705947
2008年 1月 3日   8时 近日点 日心距au= .983280055
2008年 7月 4日 16时 远日点 日心距au= 1.016753512
2009年 1月 4日 23时 近日点 日心距au= .983273035
2009年 7月 4日 10时 远日点 日心距au= 1.016666420
2010年 1月 3日   8时 近日点 日心距au= .983289667
2010年 7月 6日 19时 远日点 日心距au= 1.016701958
2011年 1月 4日   3时 近日点 日心距au= .983341273
2011年 7月 4日 23时 远日点 日心距au= 1.016740385
2012年 1月 5日   9时 近日点 日心距au= .983284094
2012年 7月 5日 12时 远日点 日心距au= 1.016675059
2013年 1月 2日 13时 近日点 日心距au= .983290474
2013年 7月 5日 23时 远日点 日心距au= 1.016708497
2014年 1月 4日 20时 近日点 日心距au= .983334719
2014年 7月 4日   8时 远日点 日心距au= 1.016681629
2015年 1月 4日 15时 近日点 日心距au= .983277391
2015年 7月 7日   4时 远日点 日心距au= 1.016682122
2016年 1月 3日   7时 近日点 日心距au= .983303941
2016年 7月 5日   0时 远日点 日心距au= 1.016750939
2017年 1月 4日 22时 近日点 日心距au= .983309436
2017年 7月 4日   4时 远日点 日心距au= 1.016675594
2018年 1月 3日 14时 近日点 日心距au= .983284269
2018年 7月 7日   1时 远日点 日心距au= 1.016696059
2019年 1月 3日 13时 近日点 日心距au= .983301165
2019年 7月 5日   6时 远日点 日心距au= 1.016754346
2020年 1月 5日 16时 近日点 日心距au= .983243565
2020年 7月 4日 20时 远日点 日心距au= 1.016694252
2021年 1月 2日 22时 近日点 日心距au= .983257061
2021年 7月 6日   6时 远日点 日心距au= 1.016729225
2022年 1月 4日 15时 近日点 日心距au= .983336540
2022年 7月 4日 15时 远日点 日心距au= 1.016715374
2023年 1月 5日   0时 近日点 日心距au= .983295578
2023年 7月 7日   4时 远日点 日心距au= 1.016680584
2024年 1月 3日   9时 近日点 日心距au= .983306994
2024年 7月 5日 13时 远日点 日心距au= 1.016725489
2025年 1月 4日 21时 近日点 日心距au= .983327407
2025年 7月 4日   4时 远日点 日心距au= 1.016643732
2026年 1月 4日   1时 近日点 日心距au= .983302057
2026年 7月 7日   2时 远日点 日心距au= 1.016643978
2027年 1月 3日 11时 近日点 日心距au= .983333464
2027年 7月 5日 13时 远日点 日心距au= 1.016728918
2028年 1月 5日 20时 近日点 日心距au= .983307358
2028年 7月 4日   6时 远日点 日心距au= 1.016679769
2029年 1月 3日   2时 近日点 日心距au= .983291733
2029年 7月 6日 13时 远日点 日心距au= 1.016712715 
2030年 1月 3日 18时 近日点 日心距au= .983341787
2030年 7月 4日 21时 远日点 日心距au= 1.016722650
2031年 1月 5日   5时 近日点 日心距au= .983266417
2031年 7月 6日 15时 远日点 日心距au= 1.016688174
2032年 1月 3日 13时 近日点 日心距au= .983246889
2032年 7月 5日 20时 远日点 日心距au= 1.016750975
2033年 1月 4日 20时 近日点 日心距au= .983298950
2033年 7月 4日   5时 远日点 日心距au= 1.016693615
2034年 1月 4日 13时 近日点 日心距au= .983289322
2034年 7月 7日   3时 远日点 日心距au= 1.016670320
2035年 1月 3日   9时 近日点 日心距au= .983324943
2035年 7月 6日   2时 远日点 日心距au= 1.016740637
2036年 1月 5日 22时 近日点 日心距au= .983320205
2036年 7月 4日   5时 远日点 日心距au= 1.016663277
2037年 1月 3日 12时 近日点 日心距au= .983288904
2037年 7月 6日 20时 远日点 日心距au= 1.016665145
2038年 1月 3日 13时 近日点 日心距au= .983354888
2038年 7月 5日   4时 远日点 日心距au= 1.016690873
2039年 1月 5日 15时 近日点 日心距au= .983311263
2039年 7月 5日 21时 远日点 日心距au= 1.016658816
2040年 1月 3日 20时 近日点 日心距au= .983293650
2040年 7月 6日   3时 远日点 日心距au= 1.016727117
2041年 1月 4日   6时 近日点 日心距au= .983347104
2041年 7月 4日 10时 远日点 日心距au= 1.016688660
2042年 1月 4日 17时 近日点 日心距au= .983301446
2042年 7月 6日 21时 远日点 日心距au= 1.016655394
2043年 1月 3日   6时 近日点 日心距au= .983288203
2043年 7月 6日 10时 远日点 日心距au= 1.016744148
2044年 1月 5日 21时 近日点 日心距au= .983289623
2044年 7月 3日 23时 远日点 日心距au= 1.016695986
2045年 1月 3日 23时 近日点 日心距au= .983265338
2045年 7月 6日 21时 远日点 日心距au= 1.016688827
2046年 1月 3日   9时 近日点 日心距au= .983345053
2046年 7月 5日 14时 远日点 日心距au= 1.016726549
2047年 1月 5日 20时 近日点 日心距au= .983321594
2047年 7月 5日 15时 远日点 日心距au= 1.016672803
2048年 1月 4日   2时 近日点 日心距au= .983281772
2048年 7月 6日 13时 远日点 日心距au= 1.016707153
2049年 1月 3日 18时 近日点 日心距au= .983334217
2049年 7月 4日 17时 远日点 日心距au= 1.016672172 

使用特权

评论回复
8
linqing171| | 2008-11-11 15:14 | 只看该作者

看看误差多大,数据来了

2008年二十四节气时间表                 
节气    日期+时间    偏差    按365.2522的误差    误差累积
小寒    2008-1-5 13:10            
大寒    2008-1-20 6:29    14.72152778    -0.497313889    0
立春    2008-2-4 19:03    15.52361111    0.304769444    -0.497313889
雨水    2008-2-19 14:57    14.82916667    -0.389675    -0.192544444
惊蛰    2008-3-5 13:13    14.92777778    -0.291063889    -0.582219444
春分    2008-3-20 14:10    15.03958333    -0.179258333    -0.873283333
清明    2008-4-4 18:16    15.17083333    -0.048008333    -1.052541667
谷雨    2008-4-20 1:29    15.30069444    0.081852778    -1.10055
立夏    2008-5-5 11:50    15.43125    0.212408333    -1.018697222
小满    2008-5-19 0:51    13.54236111    -1.676480556    -0.806288889
芒种    2008-6-5 16:12    17.63958333    2.420741667    -2.482769444
夏至    2008-6-21 8:57    15.69791667    0.479075    -0.062027778
小暑    2008-7-7 2:35    15.73472222    0.515880556    0.417047222
大暑    2008-7-22 19:50    15.71875    0.499908333    0.932927778
立秋    2008-8-7 12:18    15.68611111    0.467269444    1.432836111
处暑    2008-8-23 2:46    15.60277778    0.383936111    1.900105556
白露    2008-9-7 15:02    15.51111111    0.292269444    2.284041667
秋分    2008-9-22 0:10    14.38055556    -0.838286111    2.576311111
寒露    2008-10-8 6:26    16.26111111    1.042269444    1.738025
霜降    2008-10-23 9:16    15.11805556    -0.100786111    2.780294444
立冬    2008-11-7 9:21    15.00347222    -0.215369444    2.679508333
小雪    2008-11-22 6:38    14.88680556    -0.332036111    2.464138889
大雪    2008-12-7 2:01    14.80763889    -0.411202778    2.132102778
冬至    2008-12-21 10:51    14.36805556    -0.850786111    1.7209

使用特权

评论回复
9
linqing171| | 2008-11-11 15:21 | 只看该作者

刚又搜了一下,专家说我的数据是错的。

http://sztqb.sznews.com/html/2008-01/21/content_37638.htm

使用特权

评论回复
10
李冬发| | 2008-11-12 17:25 | 只看该作者

4楼的guosr,晕。

地球公转轨道的短半轴为14,900万千米,长半轴为14,958万千米。你说说直接等分能有多大的误差?!

使用特权

评论回复
11
guosr| | 2008-11-13 13:39 | 只看该作者

回楼上:误差大到足以影响历法

    一两天的误差从“年”的尺度上看,的确不算多大的误差,但历法讲究精确,古代的人恐怕都不能容忍一两天的历法误差,更何况是现代人。如果你买一份日历,立春、清明、夏至、冬至之类的节气标注错误,你感觉如何?
    另外,节气并非指某一天,而是某个时刻,例如冬至就是太阳直射南回归线的那一瞬间,这一瞬间所在的那一天被称为冬至日。假设某个节气出现在凌晨零点左右,那么几秒钟的误差,就会导致日历上标注的节气出现查错。从这个角度讲,中国和韩国、日本的农历是不同的,它们之间可能出现一天的误差,因为韩国、日本在东九时区,而我们是东八区。
    地球公转轨道是椭圆,导致我们国家的农历历法上一个很有意思的事情:闰月多出现在农历5、6、7、8月份,而不会出现在十一、腊月、正月。当某个农历月份中,只有一个节气的时候,这个月被称为上个月的闰月。因为地球在远日点的时候速度较低,转过15度角需要的时间稍长,因此可能在此期间出现一个农历月份无法容纳两个节气,因此闰月多出现在夏季。而在地球的近日点,地球运动速度较高,转过15度角需要的时间稍短,总可以在一个月内容纳两个节气,因此冬季很难出现闰月。基于这一点,大家就别指望出现闰正月了,过两个农历新年是不可能的。

使用特权

评论回复
12
高勇| | 2008-11-13 14:51 | 只看该作者

二十四节气并非农历里边来的

二十四节气并不是农历里边来的,农历主要以月亮为参照,但二十四节气是以黄道面和赤道面的交点来定春分和秋分。其它节气则是以地球围绕太阳每转15度为了个节气。这样二十四节气跟农历扯不是关系。
并且二十四节气的规律:“上半年逢七十二十一,下半年逢八二十三”说的也是阳历。

使用特权

评论回复
13
高勇| | 2008-11-13 15:01 | 只看该作者

我也找到一份资料

使用特权

评论回复
14
guosr| | 2008-11-13 20:53 | 只看该作者

还是数学计算最能说明问题

一年是365.2422天,即T0=365.2422*24*60*60秒。


这就是地球从近日点(注意近日点并非冬至时刻,一般在一月初)转过角度θ所需要的时间,如果知道某个节气的准确时刻,那就可以推算出此后节气的准确时刻。地球一个节气绕太阳转0.2618弧度(即15度),把0.2618*6带入上式的积分上限,可以看到累计6个节气之后,跟365.2422*6/24的平均算法相比,误差已经累计达到46.6小时,差不多两天。
把上面的表达式积分上限θ取2π,就是一年的时间长度,可以看到跟真实的回归年365.2422天相比,误差了188秒,这是因为地球轨道的基本参数的精度不够造成的,所以大家切不可把这作为精确计算的依据。
如果是做万年历,还是直接从历书上弄个查找表,程序查表最简单。

使用特权

评论回复
15
linqing171| | 2008-11-15 19:45 | 只看该作者

46.6小时,你计算的准么?

我用最大偏差来计算,也只不过三天多而已。
你用微积分做出来的还有两天?

最好是谁把今年的正确的节气贴出来,我计算一下,看看误差有多大。

使用特权

评论回复
16
高勇| | 2008-11-17 16:33 | 只看该作者

此贴讨论的问题

严重关注此贴讨论的问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

16

帖子

0

粉丝