网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  阴阳历算法(转)     
  文章作者:未知  文章来源:水木森林  
  查看:183次  录入:管理员--2007-11-17  
 
程序为: 
/*

西历农历转换程式 黄晓鸣 1995,7,25

prototype: int calconv( struct convdate * );

struct convdate
{
    int source; ==0 则输入日期为西历, !=0 则输入为农历
    int solaryear; 输出或输入之西历年份
    int solarmonth; 西历月
    int solardate; 西历日
    int lunaryear; 输出或输入之农历年份
    int lunarmonth; 农历月
    int lunardate; 农历日
    int weekday; 该日为星期几 ( 0==星期日, 1==星期一, ... )
    int kan; 该日天干 ( 0==甲, 1==乙, ..., 9==癸 )
    int chih; 该日地支 ( 0==子, 1==丑, ..., 11==亥 )
};

呼叫时须设定 souce 的值, 若为 0 则为西历转农历, 否则为农历转西历. 然後视
输入为西历或农历来设定西历或农历的年月日. 转换後的年月日会填入结构中( 农
历或西历 ), 以及该日为星期几, 天干地支.
若函式的返回值为 0 表示没有错误, 1 为输入之年份错误, 2 为输入之月份错误,
3 为输入之日期错误.
输入之西历年须在 1937 - 2031 间
输入之农历年须在 1936 - 2030 间
若须扩充, 则增加 lunarcal[]

*/

#define firstyear 1936 /* the first year in lunarcal[] */

struct convdate
{
    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 月 1 日为星期几再减 1 */
    int basekanchih; /* 此年西历 1 月 1 日之干支序号减 1 */
    int monthdays[13]; /* 此农历年每月之大小, 0==小月(29日), 1==大月(30日)*/
};

struct taglunarcal lunarcal[] = {
, /* 1936 */
,
,
,
, /* 1940 */
,
,
,
, /* 1944 */
,
,
,
, /* 1948 */
,
,
,
, /* 1952 */
,
,
,
, /* 1956 */
,
,
,
, /* 1960 */
,
,
,
, /* 1964 */
,
,
,
, /* 1968 */
,
,
,
, /* 1972 */
,
,
,
, /* 1976 */
,
,
,
, /* 1980 */
,
,
,
, /* 1984 */
,
,
,
, /* 1988 */
,
,
,
, /* 1992 */
,
,
,
, /* 1996 */
,
,
,
, /* 2000 */
,
,
,
, /* 2004 */
,
,
,
, /* 2008 */
,
,
,
, /* 2012 */
,
,
,
, /* 2016 */
,
,
,
, /* 2020 */
,
,
,
, /* 2024 */
,
,
,
, /* 2028 */
,
,
 };

#define lastyear (firstyear+sizeof(lunarcal)/sizeof(struct taglunarcal)-1)

/* 西历年每月之日数 */
int solarcal[12] = ;

/* 西历年每月之累积日数, 平年与闰年 */
int solardays[2][14] = {
,
 };

/* 求此西历年是否为闰年, 返回 0 为平年, 1 为闰年 */
int getleap( int year )
{
    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 ) /* solar */
    {
        if ( cd->solaryear <= firstyear || cd->solaryear > lastyear )
            return 1;
        sm = cd->solarmonth - 1;
        if ( sm < 0 || sm > 11 )
            return 2;
        leap = getleap( cd->solaryear );
        if ( sm == 1 )
            d = leap + 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].basedays )
        {
            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;
    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 )
            return 1;
        y = cd->lunaryear - firstyear;
        im = lunarcal[y].intercalation;
        lm = cd->lunarmonth;
        if ( lm < 0 )
        {
            if ( lm != -im )
                return 2;
        }
        else if ( lm < 1 || lm > 12 )
            return 2;
        if ( im != 0 )
        {
            if ( lm > im )
                lm++;
            else if ( lm == -im )
                lm = im + 1;
        }
        lm--;
        if ( cd->lunardate > lunarcal[y].monthdays[lm] + 29 )
            return 3;
        acc = lunarcal[y].basedays;
        for ( i=0; i acc += lunarcal[y].monthdays[i] + 29;
            acc += cd->lunardate;
            leap = getleap( cd->lunaryear );
        for ( i=13; i>=0; i-- )
            if ( acc > solardays[leap][i] )
                break;
            cd->solardate = acc - solardays[leap][i];
            if ( i <= 11 )
            {
                cd->solaryear = cd->lunaryear;
                cd->solarmonth = i + 1;
            }
            else
            {
                cd->solaryear = cd->lunaryear + 1;
                cd->solarmonth = i - 11;
            }
            leap = getleap( cd->solaryear );
            y = cd->solaryear - firstyear;
            acc = solardays[leap][cd->solarmonth-1] + cd->solardate;
            cd->weekday = ( acc + lunarcal[y].baseweekday ) % 7;
            kc = acc + lunarcal[y].basekanchih;
            cd->kan = kc % 10;
            cd->chih = kc % 12;
        }
return 0;
}
 
 
上一篇: 以小博大 java性能优化技巧集锦    下一篇: java基础:java 启动器如何查找类
  相关文档
spring+ibatis 数据化持久层(转) 11-17
一个软件测试工程师的加班经历 11-17
用javascript+php随机显示图片 11-17
专家讲解优化Derby数据库程序性能 04-14
用actionform一次获取表单所有参数 11-17
java教程 第三讲 java语言中的面向对象特性 11-17
编写注释生成javadoc html文档 11-17
excel的java处理方式 11-17
rms 从入门到精通౿.. 11-17
分享——一个简单的mp3播放器的制作 11-17
touppercase 方法 11-16
j2me编程最佳实践之屏幕导航 11-16
每个初学java者都应该搞懂的问题 11-17
java api混排算法 11-17
内存泄漏,走开 轻松搞定java内存泄漏 11-16
简谈java将数据库中的数据写入到word 12-24
web services:处理xml字符串中特殊字符 12-25
编程必备经典:java常见问题集锦(2) 11-16
java学习之了解java的运行环境 11-17
说说java的args大家可能没有注意到的现象 11-17
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息