公历转农历linux C程序

该代码实现根据公历日期查询农历日期,和24节气,假期,干支年份,干支月份等。

改代码是根据以下两个代码改编而来,感谢两位的共享精神。

http://blog.jjonline.cn/userInterFace/173.html
1900年至2100年公历、农历互转Js代码
http://www.cnblogs.com/qintangtao/archive/2013/03/01/2938887.html
阳历转阴历算法概述

其中没有实现干支日期,以为确实没有仔细研究,而且感觉也没有多大意义。

代码如下,这个只是个源代码,如果需要,可以自己进行功能封装。

#include 
#include 
#include 
#include 
#include 


struct solar_holiday {
	int month;
	int day;
	char *holiday_name;
};

struct lunar_holiday {
	int month;
	int day;
	char *holiday_name;
};

struct week_holiday {
	int month;
	int week_at_month;
	int week_day;
	char *holiday_name;
};

//-------------------------------------------------------------------
//按公历计算的节日
struct solar_holiday solar_holiday_info[] = {
	{1, 1, "元旦"},
	{2, 2, "世界湿地日"},
	{2, 10, "国际气象节"},
	{2, 14, "情人节"},
	{3, 1, "国际海豹日"},
	{3, 5, "学雷锋纪念日"},
	{3, 8, "妇女节"},
	{3, 12, "植树节 孙中山逝世纪念日"},
	{3, 14, "国际警察日"},
	{3, 15, "消费者权益日"},
	{3, 17, "中国国医节 国际航海日"},
	{3, 21, "世界森林日 消除种族歧视国际日 世界儿歌日"},
	{3, 22, "世界水日"},
	{3, 24, "世界防治结核病日"},
	{4, 1, "愚人节"},
	{4, 7, "世界卫生日"},
	{4, 22, "世界地球日"},
	{5, 1, "劳动节"},
	{5, 2, "劳动节假日"},
	{5, 3, "劳动节假日"},
	{5, 4, "青年节"},
	{5, 8, "世界红十字日"},
	{5, 12, "国际护士节"},
	{5, 31, "世界无烟日"},
	{6, 1, "国际儿童节"},
	{6, 5, "世界环境保护日"},
	{6, 26, "国际禁毒日"},
	{7, 1, "建党节 香港回归纪念 世界建筑日"},
	{7, 11, "世界人口日"},
	{8, 1, "建军节"},
	{8, 8, "中国男子节 父亲节"},
	{8, 15, "抗日战争胜利纪念"},
	{9, 10, "教师节"},
	{9, 18, "九·一八事变纪念日"},
	{9, 20, "国际爱牙日"},
	{9, 27, "世界旅游日"},
	{9, 28, "孔子诞辰"},
	{10, 1, "国庆节 国际音乐日"},
	{10, 2, "国庆节假日"},
	{10, 3, "国庆节假日"},
	{10, 6, "老人节"},
	{10, 24, "联合国日"},
	{11, 10, "世界青年节"},
	{11, 12, "孙中山诞辰纪念"},
	{12, 1, "世界艾滋病日"},
	{12, 3, "世界残疾人日"},
	{12, 20, "澳门回归纪念"},
	{12, 24, "平安夜"},
	{12, 25, "圣诞节"}
};

//按农历计算的节日
struct lunar_holiday lunar_holiday_info[] = {
	{1, 1, "春节"},
	{1, 15, "元宵节"},
	{5, 5, "端午节"},
	{7, 7, "七夕情人节"},
	{7, 15, "中元节 盂兰盆节"},
	{8, 15, "中秋节"},
	{9, 9, "重阳节"},
	{12, 8, "腊八节"},
	{12, 23, "北方小年(扫房)"},
	{12, 24, "南方小年(掸尘)"},
	{12, 30, "除夕"}
};

//按某月第几个星期几
struct week_holiday week_holiday_info[] = {
	{5, 2, 1, "母亲节"},
	{5, 3, 1, "全国助残日"},
	{6, 3, 1, "父亲节"},
	{9, 3, 3, "国际和平日"},
	{9, 4, 1, "国际聋人节"},
	{10, 1, 2, "国际住房日"},
	{10, 1, 4, "国际减轻自然灾害日"},
	{11, 4, 5, "感恩节"}
};
//------------------------------------------------------------------------------------
//60S*60M*24H=86400S
#define SECOND_IN_DAY 86400
/**
* @1900-2100区间内的公历、农历互转
* @charset UTF-8
* @Author  Jea杨([email protected])
* @Time    2014-7-21
* @Time    2016-8-13 Fixed 2033hex、Attribution Annals
* @Time    2016-9-25 Fixed lunar LeapMonth Param Bug
* @Time    2017-7-24 Fixed use get_term Func Param Error.use solar year,NOT lunar year
* @Version 1.0.3
* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
*/
/**
  * 农历1900-2100的润大小信息表
  * @Array Of Property
  * @return Hex
  */
int lunar_info[] = {0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909
                    0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919
                    0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929
                    0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939
                    0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949
                    0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959
                    0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969
                    0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979
                    0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989
                    0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,//1990-1999
                    0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009
                    0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019
                    0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029
                    0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039
                    0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049
                    /**Add By [email protected]**/
                    0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50,0x06b20,0x1a6c4,0x0aae0,//2050-2059
                    0x0a2e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069
                    0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079
                    0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089
                    0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099
                    0x0d520
                   };

/**
  * 公历每个月份的天数普通表
  * @Array Of Property
  * @return Number
  */
int solar_month[] = {31,28,31,30,31,30,31,31,30,31,30,31};

/**
  * 天干地支之天干速查表
  * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
  * @return Cn string
  */
char *tian_gan[] = {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};

/**
  * 天干地支之地支速查表
  * @Array Of Property
  * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
  * @return Cn string
  */
char *di_zhi[] = {"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};

/**
  * 天干地支之地支速查表<=>生肖
  * @Array Of Property
  * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
  * @return Cn string
  */
char *Chinese_zodiac[] = {"鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"};

/**
  * 24节气速查表
  * @Array Of Property
  * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
  * @return Cn string
  */
char *solar_terms[] = {"小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"};

char *horoscope[] = {"魔羯座", "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "魔羯座"};

/**
  * 1900-2100各年的24节气日期速查表
  * @Array Of Property
  * @return 0x string For splice
  */
char *solar_terms_qlist[] = {"9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf97c3598082c95f8c965cc920f",
                             "97bd0b06bdb0722c965ce1cfcc920f","b027097bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e",
                             "97bcf97c359801ec95f8c965cc920f","97bd0b06bdb0722c965ce1cfcc920f","b027097bd097c36b0b6fc9274c91aa",
                             "97b6b97bd19801ec9210c965cc920e","97bcf97c359801ec95f8c965cc920f","97bd0b06bdb0722c965ce1cfcc920f",
                             "b027097bd097c36b0b6fc9274c91aa","9778397bd19801ec9210c965cc920e","97b6b97bd19801ec95f8c965cc920f",
                             "97bd09801d98082c95f8e1cfcc920f","97bd097bd097c36b0b6fc9210c8dc2","9778397bd197c36c9210c9274c91aa",
                             "97b6b97bd19801ec95f8c965cc920e","97bd09801d98082c95f8e1cfcc920f","97bd097bd097c36b0b6fc9210c8dc2",
                             "9778397bd097c36c9210c9274c91aa","97b6b97bd19801ec95f8c965cc920e","97bcf97c3598082c95f8e1cfcc920f",
                             "97bd097bd097c36b0b6fc9210c8dc2","9778397bd097c36c9210c9274c91aa","97b6b97bd19801ec9210c965cc920e",
                             "97bcf97c3598082c95f8c965cc920f","97bd097bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa",
                             "97b6b97bd19801ec9210c965cc920e","97bcf97c3598082c95f8c965cc920f","97bd097bd097c35b0b6fc920fb0722",
                             "9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf97c359801ec95f8c965cc920f",
                             "97bd097bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e",
                             "97bcf97c359801ec95f8c965cc920f","97bd097bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa",
                             "97b6b97bd19801ec9210c965cc920e","97bcf97c359801ec95f8c965cc920f","97bd097bd07f595b0b6fc920fb0722",
                             "9778397bd097c36b0b6fc9210c8dc2","9778397bd19801ec9210c9274c920e","97b6b97bd19801ec95f8c965cc920f",
                             "97bd07f5307f595b0b0bc920fb0722","7f0e397bd097c36b0b6fc9210c8dc2","9778397bd097c36c9210c9274c920e",
                             "97b6b97bd19801ec95f8c965cc920f","97bd07f5307f595b0b0bc920fb0722","7f0e397bd097c36b0b6fc9210c8dc2",
                             "9778397bd097c36c9210c9274c91aa","97b6b97bd19801ec9210c965cc920e","97bd07f1487f595b0b0bc920fb0722",
                             "7f0e397bd097c36b0b6fc9210c8dc2","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e",
                             "97bcf7f1487f595b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa",
                             "97b6b97bd19801ec9210c965cc920e","97bcf7f1487f595b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722",
                             "9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf7f1487f531b0b0bb0b6fb0722",
                             "7f0e397bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e",
                             "97bcf7f1487f531b0b0bb0b6fb0722","7f0e397bd07f595b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa",
                             "97b6b97bd19801ec9210c9274c920e","97bcf7f0e47f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722",
                             "9778397bd097c36b0b6fc9210c91aa","97b6b97bd197c36c9210c9274c920e","97bcf7f0e47f531b0b0bb0b6fb0722",
                             "7f0e397bd07f595b0b0bc920fb0722","9778397bd097c36b0b6fc9210c8dc2","9778397bd097c36c9210c9274c920e",
                             "97b6b7f0e47f531b0723b0b6fb0722","7f0e37f5307f595b0b0bc920fb0722","7f0e397bd097c36b0b6fc9210c8dc2",
                             "9778397bd097c36b0b70c9274c91aa","97b6b7f0e47f531b0723b0b6fb0721","7f0e37f1487f595b0b0bb0b6fb0722",
                             "7f0e397bd097c35b0b6fc9210c8dc2","9778397bd097c36b0b6fc9274c91aa","97b6b7f0e47f531b0723b0b6fb0721",
                             "7f0e27f1487f595b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa",
                             "97b6b7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722",
                             "9778397bd097c36b0b6fc9274c91aa","97b6b7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722",
                             "7f0e397bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b7f0e47f531b0723b0b6fb0721",
                             "7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722","9778397bd097c36b0b6fc9274c91aa",
                             "97b6b7f0e47f531b0723b0787b0721","7f0e27f0e47f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722",
                             "9778397bd097c36b0b6fc9210c91aa","97b6b7f0e47f149b0723b0787b0721","7f0e27f0e47f531b0723b0b6fb0722",
                             "7f0e397bd07f595b0b0bc920fb0722","9778397bd097c36b0b6fc9210c8dc2","977837f0e37f149b0723b0787b0721",
                             "7f07e7f0e47f531b0723b0b6fb0722","7f0e37f5307f595b0b0bc920fb0722","7f0e397bd097c35b0b6fc9210c8dc2",
                             "977837f0e37f14998082b0787b0721","7f07e7f0e47f531b0723b0b6fb0721","7f0e37f1487f595b0b0bb0b6fb0722",
                             "7f0e397bd097c35b0b6fc9210c8dc2","977837f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721",
                             "7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722","977837f0e37f14998082b0787b06bd",
                             "7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722",
                             "977837f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722",
                             "7f0e397bd07f595b0b0bc920fb0722","977837f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721",
                             "7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722","977837f0e37f14998082b0787b06bd",
                             "7f07e7f0e47f149b0723b0787b0721","7f0e27f0e47f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722",
                             "977837f0e37f14998082b0723b06bd","7f07e7f0e37f149b0723b0787b0721","7f0e27f0e47f531b0723b0b6fb0722",
                             "7f0e397bd07f595b0b0bc920fb0722","977837f0e37f14898082b0723b02d5","7ec967f0e37f14998082b0787b0721",
                             "7f07e7f0e47f531b0723b0b6fb0722","7f0e37f1487f595b0b0bb0b6fb0722","7f0e37f0e37f14898082b0723b02d5",
                             "7ec967f0e37f14998082b0787b0721","7f07e7f0e47f531b0723b0b6fb0722","7f0e37f1487f531b0b0bb0b6fb0722",
                             "7f0e37f0e37f14898082b0723b02d5","7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721",
                             "7f0e37f1487f531b0b0bb0b6fb0722","7f0e37f0e37f14898082b072297c35","7ec967f0e37f14998082b0787b06bd",
                             "7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e37f0e37f14898082b072297c35",
                             "7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722",
                             "7f0e37f0e366aa89801eb072297c35","7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f149b0723b0787b0721",
                             "7f0e27f1487f531b0b0bb0b6fb0722","7f0e37f0e366aa89801eb072297c35","7ec967f0e37f14998082b0723b06bd",
                             "7f07e7f0e47f149b0723b0787b0721","7f0e27f0e47f531b0723b0b6fb0722","7f0e37f0e366aa89801eb072297c35",
                             "7ec967f0e37f14998082b0723b06bd","7f07e7f0e37f14998083b0787b0721","7f0e27f0e47f531b0723b0b6fb0722",
                             "7f0e37f0e366aa89801eb072297c35","7ec967f0e37f14898082b0723b02d5","7f07e7f0e37f14998082b0787b0721",
                             "7f07e7f0e47f531b0723b0b6fb0722","7f0e36665b66aa89801e9808297c35","665f67f0e37f14898082b0723b02d5",
                             "7ec967f0e37f14998082b0787b0721","7f07e7f0e47f531b0723b0b6fb0722","7f0e36665b66a449801e9808297c35",
                             "665f67f0e37f14898082b0723b02d5","7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721",
                             "7f0e36665b66a449801e9808297c35","665f67f0e37f14898082b072297c35","7ec967f0e37f14998082b0787b06bd",
                             "7f07e7f0e47f531b0723b0b6fb0721","7f0e26665b66a449801e9808297c35","665f67f0e37f1489801eb072297c35",
                             "7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722"
                            };

/**
  * 数字转中文速查表
  * @Array Of Property
  * @trans ['日','一','二','三','四','五','六','七','八','九','十']
  * @return Cn string
  */
char *Chinese_num[] = {"日","一","二","三","四","五","六","七","八","九","十"};

/**
  * 日期转农历称呼速查表
  * @Array Of Property
  * @trans ['初','十','廿','卅']
  * @return Cn string
  */
char *lunar_num[] = {"初","十","廿","卅"};

/**
  * 月份转农历称呼速查表
  * @Array Of Property
  * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
  * @return Cn string
  */
char *lunar_month[] = {"正月","二月","三月","四月","五月","六月","七月","八月","九月","十月","冬月","腊月"};


/**
  * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
  * @param lunar Year
  * @return Number (0-12)
  * @eg:var leap_month = calendar.leap_month(1987) ;//leap_month=6
  */
int leap_month(int y)   //闰字编码 \u95f0
{
	return(lunar_info[y-1900] & 0xf);
};

/**
  * 返回农历y年闰月的天数 若该年没有闰月则返回0
  * @param lunar Year
  * @return Number (0、29、30)
  * @eg:var leapMonthDay = calendar.leap_days(1987) ;//leapMonthDay=29
  */
int leap_days(int y)
{
	if(leap_month(y))  {
		return((lunar_info[y-1900] & 0x10000)? 30: 29);
	}
	return(0);
};

/**
  * 返回农历y年一整年的总天数
  * @param lunar Year
  * @return Number
  * @eg:var count = calendar.leap_year_days(1987) ;//count=387
  */
int leap_year_days(int y)
{
	int i, sum = 348;
	for(i=0x8000; i>0x8; i>>=1) {
		sum += (lunar_info[y-1900] & i)? 1: 0;
	}
	return(sum+leap_days(y));
};

/**
  * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
  * @param lunar Year
  * @return Number (-1、29、30)
  * @eg:var MonthDay = calendar.month_days(1987,9) ;//MonthDay=29
  */
int month_days(int y,int m)
{
	if(m>12 || m<1)
		return -1;//月份参数从1至12,参数错误返回-1
	return( (lunar_info[y-1900] & (0x10000>>m))? 30: 29 );
};

/**
  * 返回公历(!)y年m月的天数
  * @param solar Year
  * @return Number (-1、28、29、30、31)
  * @eg:var solarMonthDay = calendar.leap_days(1987) ;//solarMonthDay=30
  */
int solar_days(int y,int m)
{
	if(m>12 || m<1) {
		return -1;
	} //若参数错误 返回-1
	int ms = m-1;
	if(ms==1) { //2月份的闰平规律测算后确认返回28或29
		return(((y%4 == 0) && (y%100 != 0) || (y%400 == 0))? 29: 28);
	} else {
		return(solar_month[ms]);
	}
};

/**
 * 农历年份转换为干支纪年
 * @param  lYear 农历年的年份数
 * @return Cn string
 */
int to_ganzhi_year(int lYear, char **OGan, char **OZhi)
{
	int ganKey = (lYear - 3) % 10;
	int zhiKey = (lYear - 3) % 12;
	if(ganKey == 0) ganKey = 10;//如果余数为0则为最后一个天干
	if(zhiKey == 0) zhiKey = 12;//如果余数为0则为最后一个地支

	*OGan = tian_gan[ganKey-1];
	*OZhi = di_zhi[zhiKey-1];
	return 0;

};

/**
 * 公历月、日判断所属星座
 * @param  cMonth [description]
 * @param  cDay [description]
 * @return Cn string
 */
char *to_horoscope(int cMonth, int cDay)
{
	char arr[] = {20,19,21,21,21,22,23,23,23,23,22,22};
	return horoscope[(cMonth - (cDay < arr[cMonth-1] ? 1 : 0))%12];
}

/**
  * 传入offset偏移量返回干支
  * @param offset 相对甲子的偏移量
  * @return Cn string
  */
int to_ganzhi(int offset, char **OGan, char **OZhi)
{
	*OGan = tian_gan[offset%10];
	*OZhi = di_zhi[offset%12];
	return 0;
};

int parseint(char *table, int begin, int len)
{
	char a[32] = {0};
	strncpy(a, (table+begin), len);
	char *endptr, *str;
	long i = strtol(a, &endptr, 16);
	if (endptr == a) {
		fprintf(stderr, "No digits were found\n");
	}
	return (int)i;
}

/**
  * 传入公历(!)y年获得该年第n个节气的公历日期
  * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
  * @return day Number
  * @eg:var _24 = calendar.get_term(1987,3) ;//_24=4;意即1987年2月4日立春
  */
int get_term(int y, int n)
{
	if(y<1900 || y>2100) {
		return -1;
	}
	if(n<1 || n>24) {
		return -1;
	}
	char *_table = solar_terms_qlist[y-1900];
	int _info[] = {
		parseint(_table, 0, 5),
		parseint(_table, 5, 5),
		parseint(_table, 10, 5),
		parseint(_table, 15, 5),
		parseint(_table, 20, 5),
		parseint(_table, 25, 5)
	};

	int _calday[] = {
		(_info[0]/100000),
		(_info[0]%100000/1000),
		(_info[0]%1000/100),
		(_info[0]%100),

		(_info[1]/100000),
		(_info[1]%100000/1000),
		(_info[1]%1000/100),
		(_info[1]%100),

		(_info[2]/100000),
		(_info[2]%100000/1000),
		(_info[2]%1000/100),
		(_info[2]%100),

		(_info[3]/100000),
		(_info[3]%100000/1000),
		(_info[3]%1000/100),
		(_info[3]%100),

		(_info[4]/100000),
		(_info[4]%100000/1000),
		(_info[4]%1000/100),
		(_info[4]%100),

		(_info[5]/100000),
		(_info[5]%100000/1000),
		(_info[5]%1000/100),
		(_info[5]%100)
	};
	return (_calday[n-1]);
};

/**
  * 传入农历数字月份返回汉语通俗表示法
  * @param lunar month
  * @return Cn string
  * @eg:var cnMonth = calendar.to_Chinese_month(12) ;//cnMonth='腊月'
  */
char *to_Chinese_month(int m)   // 月 => \u6708
{
	if(m>12 || m<1) {
		return NULL;
	} //若参数错误 返回-1
	char *s = lunar_month[m-1];
	return s;
};

/**
  * 传入农历日期数字返回汉字表示法
  * @param lunar day
  * @return Cn string
  * @eg:var cnDay = calendar.to_Chinese_day(21) ;//cnMonth='廿一'
  */
char Chinese_day[13];
char *to_Chinese_day(int d)  //日 => \u65e5
{
	memset(Chinese_day, 0, 13);
	switch (d) {
	case 10:
		strcpy(Chinese_day, "初十");
		break;
	case 20:
		strcpy(Chinese_day, "二十");
		break;
	case 30:
		strcpy(Chinese_day, "三十");
		break;
	default :
		strcpy(Chinese_day, lunar_num[(d/10)]);
		strcat(Chinese_day, Chinese_num[(d%10)]);
	}
	return(Chinese_day);
};

/**
  * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
  * @param y year
  * @return Cn string
  * @eg:var animal = calendar.get_Chinese_zodiac(1987) ;//animal='兔'
  */
char *get_Chinese_zodiac(int y)
{
	return Chinese_zodiac[(y - 4) % 12];
};

int caculate_week_day(int y,int m, int d)
{
	if(m==1||m==2) {
		m+=12;
		y--;
	}
	int iWeek=((d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)+1)%7;
	return iWeek;
}

int date_UTC(int y,int m,int d)
{
	struct tm p;
	p.tm_sec = 0;         /* seconds */
	p.tm_min = 0;         /* minutes */
	p.tm_hour = 0;        /* hours */
	p.tm_mday = d;        /* day of the month */
	p.tm_mon = (m-1);         /* month */
	p.tm_year = (y-1900);        /* year */
	return mktime(&p);
}

// 比较当天是不是指定的第周几
bool compare_week_day_holiday(struct week_holiday week_holiday_info, int y, int m, int d)
{
	bool ret = false;

	if (week_holiday_info.month == m) { //月份相同
		int nweek = caculate_week_day(y,m,d);
		if (week_holiday_info.week_day == nweek) { //星期几相同
			int cntweek = 1;

			while((d-7*cntweek)>0)
				cntweek++;

			printf("cntweek:%d\n", cntweek);

			if (week_holiday_info.week_at_month == cntweek) {
				ret = true;
			}
		}
	}

	return ret;
}

/**
  * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
  * @param y  solar year
  * @param m  solar month
  * @param d  solar day
  * @return JSON object
  * @eg:console.log(calendar.solar2lunar(1987,11,01));
  */
int solar2lunar (int y,int m,int d)   //参数区间1900.1.31~2100.12.31
{
	//年份限定、上限
	if(y<1900 || y>2100) {
		return -1;// undefined转换为数字变为NaN
	}
	//公历传参最下限
	if(y==1900&&m==1&&d<31) {
		return -1;
	}

	int offset = (date_UTC(y,m,d) - date_UTC(1970,2,6))/SECOND_IN_DAY;

	int i, temp;
	for(i=1970; i<2101 && offset>0; i++) {
		temp    = leap_year_days(i);
		offset -= temp;
	}
	if(offset < 0) {
		offset += temp;
		i--;
	}

	//星期几
	int nWeek = caculate_week_day(y,m,d);
	char *cWeek  = Chinese_num[nWeek];
	//数字表示周几顺应天朝周一开始的惯例
	if(nWeek==0) {
		nWeek = 7;
	}


	//农历年
	int year   = i;
	int leap   = leap_month(i); //闰哪个月
	int isLeap = false;

	//效验闰月
	for(i=1; i<13 && offset>0; i++) {
		//闰月
		if(leap>0 && i==(leap+1) && isLeap==false) {
			--i;
			isLeap = true;
			temp = leap_days(year); //计算农历闰月天数
		} else {
			temp = month_days(year, i);//计算农历普通月天数
		}
		//解除闰月
		if(isLeap==true && i==(leap+1)) {
			isLeap = false;
		}
		offset -= temp;
	}
	// 闰月导致数组下标重叠取反
	if(offset==0 && leap>0 && i==leap+1) {
		if(isLeap) {
			isLeap = false;
		} else {
			isLeap = true;
			--i;
		}
	}
	if(offset<0) {
		offset += temp;
		--i;
	}
	//农历月
	int month      = i;
	//农历日
	int day        = offset + 1;
	//天干地支处理
	int sm         = m-1;
	char *ygz, *ygg;
	to_ganzhi_year(year, &ygg, &ygz);

	// 当月的两个节气
	// bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
	int firstNode  = get_term(y,(m*2-1));//返回当月「节」为几日开始
	int secondNode = get_term(y,(m*2));//返回当月「节」为几日开始

	char *mgz, *mgg;
	// 依据12节气修正干支月
	to_ganzhi((y-1900)*12+m+11, &mgg, &mgz);
	if(d>=firstNode) {
		to_ganzhi((y-1900)*12+m+12, &mgg, &mgz);
	}

	//传入的日期的节气与否
	bool isTerm = false;
	char *Term   = NULL;
	if(firstNode==d) {
		isTerm  = true;
		Term    = solar_terms[m*2-2];
	}
	if(secondNode==d) {
		isTerm  = true;
		Term    = solar_terms[m*2-1];
	}
	/*//日柱 当月一日与 1970/1/13 相差天数
	char *dgz, *dgg;
	int dayCyclical = date_UTC(y,m,d)/SECOND_IN_DAY - date_UTC(2017,1,6)/SECOND_IN_DAY;
	to_ganzhi(dayCyclical, &dgg, &dgz);*/
	//该日期所属的星座
	char *horoscope       = to_horoscope(m,d);

	//查找按某月第几个星期几
	for(i=0; i<(sizeof(week_holiday_info)/sizeof(struct week_holiday)); i++) {
		if(compare_week_day_holiday(week_holiday_info[i], y, m, d))
			printf("today is %s\n", week_holiday_info[i].holiday_name);
	}

	//按农历计算的节日
	for(i=0; i<(sizeof(lunar_holiday_info)/sizeof(struct lunar_holiday)); i++) {
		if((lunar_holiday_info[i].month == month) && (lunar_holiday_info[i].day == day))
			printf("today is %s\n", lunar_holiday_info[i].holiday_name);
	}

	//按公历计算的节日
	for(i=0; i<(sizeof(solar_holiday_info)/sizeof(struct solar_holiday)); i++) {
		if((solar_holiday_info[i].month == m) && (solar_holiday_info[i].day == d))
			printf("today is %s\n", solar_holiday_info[i].holiday_name);
	}

	printf("'lYear':%d\n", year);
	printf("'lMonth':%d\n", month);
	printf("'lDay':%d\n", day);
	printf("'Animal':%s\n", get_Chinese_zodiac(year));
	if(isLeap)
		printf("闰");
	printf("'IMonthCn':%s\n", to_Chinese_month(month));
	printf("'IDayCn':%s\n", to_Chinese_day(day));
	printf("'cYear':%d\n", y);
	printf("'cMonth':%d\n", m);
	printf("'cDay':%d\n", d);
	printf("'gzYear':%s%s年\n", ygg, ygz);
	printf("'gzMonth':%s%s月\n", mgg, mgz);
	//printf("'gzDay':%s%s日\n", dgg, dgz);
	printf("'nWeek':%d\n", nWeek);
	printf("'ncWeek':%s\n", cWeek);
	printf("'isTerm':%d\n", isTerm);
	printf("'Term':%s\n", Term);
	printf("'horoscope':%s\n", horoscope);

	return 0;
};

/**
  * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
  * @param y  lunar year
  * @param m  lunar month
  * @param d  lunar day
  * @param isLeapMonth  lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
  * @return JSON object
  * @eg:console.log(calendar.lunar2solar(1987,9,10));
  */
int lunar2solar(int y, int m, int d, bool isLeapMonth)
{
	//参数区间1970.1.31~2100.12.1
	isLeapMonth = !!isLeapMonth;
	int leapOffset  = 0;
	int leap_Month   = leap_month(y);
	int leapDay     = leap_days(y);
	if(isLeapMonth&&(leap_Month!=m)) {
		return -1;       //传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
	}
	if(y==2100&&m==12&&d>1 || y==1970&&m==1&&d<31) {
		return -1;       //超出了最大极限值
	}
	int day  = month_days(y,m);
	int _day = day;
	//bugFix 2016-9-25
	//if month is leap, _day use leap_days method
	if(isLeapMonth) {
		_day = leap_days(y);
	}
	if(y < 1970 || y > 2100 || d > _day) {
		return -1;       //参数合法性效验
	}

	//计算农历的时间差
	int offset = 0, i;
	for(i=1970; i0) {
				offset+=leap_days(y);
				isAdd = true;
			}
		}
		offset+=month_days(y,i);
	}
	//转换闰月农历 需补充该年闰月的前一个月的时差
	if(isLeapMonth) {
		offset+=day;
	}
	//1970年农历正月一日的公历时间为1970年2月6日0时0分0秒(该时间也是本农历的最开始起始点)
	int stmap   =   date_UTC(1970,2,6);
	long calObj  =   (offset+d-1)*SECOND_IN_DAY+stmap;
	struct tm *ptm_out;
	ptm_out = localtime(&calObj);
	//printf("Local time and date: %d %d %d\n", ptm_out->tm_year+1900, ptm_out->tm_mon+1, ptm_out->tm_mday);
	//printf("Local time and date: %s\n", asctime(ptm_out));
	solar2lunar((ptm_out->tm_year+1900),(ptm_out->tm_mon+1),(ptm_out->tm_mday));

	return 0;
}

int main(int argc, char **argv)
{
	/*int i;
	char *gan, *zhi;
	for(i = 2001; i<2018; i++) {
		//printf("solar_days(%d) = %d\n", i, solar_days(2018, i));
		//to_ganzhi_year(i, &gan, &zhi);
		printf("%s\n", get_Chinese_zodiac(i));
	}*/

	/*int i,j;
	char *ast;
	for(j=1; j<13; j++)
	{

		for(i=1; i<31; i++)
		{
			printf("%d月%d日 %s\n", j, i, to_horoscope(j, i));
		}

	}*/
	solar2lunar(2018, 2, 14);

	lunar2solar(1994,7,7,false);

	return 0;
}

结果如下:

today is 情人节
'lYear':2017
'lMonth':12
'lDay':29
'Animal':鸡
'IMonthCn':腊月
'IDayCn':廿九
'cYear':2018
'cMonth':2
'cDay':14
'gzYear':丁酉年
'gzMonth':甲寅月
'nWeek':3
'ncWeek':三
'isTerm':0
'Term':(null)
'horoscope':水瓶座
today is 七夕情人节
'lYear':1994
'lMonth':7
'lDay':7
'Animal':狗
'IMonthCn':七月
'IDayCn':初七
'cYear':1994
'cMonth':8
'cDay':13
'gzYear':甲戌年
'gzMonth':壬申月
'nWeek':6
'ncWeek':六
'isTerm':0
'Term':(null)
'horoscope':狮子座

你可能感兴趣的:(编程语言技巧)