公式有一定的误差,不过基本上1900-2100之间会在几分钟之内。。。
很多日历上标的节气会将 子时(23:00)作为一天的开始, 这样 23:00之后就要加一天。。。
#include <stdio.h> #include <stdlib.h> static const double x_1900_1_6_2_5 = 693966.08680556; double get_solar_term( int y , int n ) { static const int termInfo[] = { 0 ,21208 ,42467 ,63836 ,85337 ,107014, 128867,150921,173149,195551,218072,240693, 263343,285989,308563,331033,353350,375494, 397447,419210,440795,462224,483532,504758 }; return x_1900_1_6_2_5+365.2422*(y-1900)+termInfo[n]/(60.*24); } int format_date( unsigned _days , char* result ); int main( int argc , char* argv[] ) { static const char* solar_term_name[] = { "小寒","大寒","立春","雨水", "惊蛰","春分","清明","谷雨", "立夏","小满","芒种","夏至", "小暑","大暑","立秋","处暑", "白露","秋分","寒露","霜降", "立冬","小雪","大雪","冬至" }; char str_d[100]; int year = 2008 , i; if( argc == 2 ) { year = atoi( argv[1] ); if( year < 1900 || year > 2099 ) year = 2008; } for( i = 0; i < 24; ++i ) { format_date( (unsigned)get_solar_term( year , i ) , str_d ); printf( "%s : %s/n" , solar_term_name[i] , str_d ); } return 0; } int format_date( unsigned _days , char* result ) { static const int mdays[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; int y , m , d , diff; unsigned days; days = 100 * (_days - _days/(3652425L/(3652425L-3652400L)) ); y = days / 36524; days %= 36524; m = 1 + days/3044; /* [1..12] */ d = 1 + (days%3044)/100; /* [1..31] */ diff =y*365+y/4-y/100+y/400+mdays[m-1]+d-((m<=2&&((y&3)==0)&&((y%100)!=0||y%400==0))) - _days; if( diff > 0 && diff >= d ) /* ~0.5% */ { if( m == 1 ) { --y; m = 12; d = 31 - ( diff - d ); } else { d = mdays[m-1] - ( diff - d ); if( --m == 2 ) d += ((y&3)==0) && ((y%100)!=0||y%400==0); } } else { if( (d -= diff) > mdays[m] ) /* ~1.6% */ { if( m == 2 ) { if(((y&3)==0) && ((y%100)!=0||y%400==0)) { if( d != 29 ) m = 3 , d -= 29; } else { m = 3 , d -= 28; } } else { d -= mdays[m]; if( m++ == 12 ) ++y , m = 1; } } } return sprintf( result , "%04d-%02d-%02d" , y , m , d ); }