您的位置:首页 > 运维架构 > Linux

公历转农历linux C程序

2018-02-05 22:24 302 查看
该代码实现根据公历日期查询农历日期,和24节气,假期,干支年份,干支月份等。

改代码是根据以下两个代码改编而来,感谢两位的共享精神。
http://blog.jjonline.cn/userInterFace/173.html
1900年至2100年公历、农历互转Js代码
http://www.cnblogs.com/qintangtao/archive/2013/03/01/2938887.html
阳历转阴历算法概述

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

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

#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>

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杨(JJonline@JJonline.Cn)
* @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 JJonline@JJonline.Cn**/
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; i<y; i++) {
offset+=leap_year_days(i);
}
int leap = 0;
bool isAdd = false;
for(i=1; i<m; i++) {
leap = leap_month(y);
if(!isAdd) {//处理闰月
if(leap<=i && leap>0) {
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':狮子座
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: