回 帖 发 新 帖 刷新版面

主题:求助 大家好,高手请指点一下

大家好,
我想用C语言编一两个程序,
请大家指点一下
最好可以把原代码和一些说明都写给我
一个是”万年历程序设计“
要求:1输入一年的日历
         2输出连续多年的日历
另外一个是“前后台音乐程序设计”
要求:在屏幕上以字符或图片显示乐曲名称的信息同时播放完整的乐曲
         可考虑以某些按键进行暂停或继续播放控制。

请各们高手们指点,万分感谢!!

回复列表 (共11个回复)

沙发

发信人: churinga (永远的CS992◎Churinga), 信区: programming
标  题: [合集]万年历算法详解(感谢vivian)
发信站: 一塌糊涂 BBS (Tue Jun 10 15:10:10 2003), 本站(ytht.net)

───────────────────────────────────────
作者 vivian         时间 Tue May  6 01:16:05 2003                            
───────────────────────────────────────
【 以下文字转载自 vivian 的信箱 】
【 原文由 Aphroditte@smth.edu.cn 所发表 】
发信人: sundew (薇子), 信区: Programming
标  题: Re: 急:请教从公历到农历的转换算法!
发信站: BBS 水木清华站 (Wed Nov 10 21:47:58 1999)

        从公历日期推对应干支
一,口诀:
        乘五除四九加日,
        双月间隔三十天。
        一二自加整少一,
        三五七八十尾前。

二,举例说明:
例一:1996年1月16日


(96*5+96/4+9+16)/60=8余49,49即为六十甲子序数。9对应天干壬,
49除12余1对应地支子,对应干支为“壬子”。

例二:1997年2月16日
(97*5+97/4+9+16+30+2)/60=9余26,26即为六十甲子序数。6对应天
干己,26除12余2对应地支丑,对应干支为“己丑”。

三,注解:
第三句中的“整少一”,为能被4整除之年一二月份比其他三年都要少
加一;第四句反映的是大月规律,即8月加3、11月加5,依此类推。
【 在 sundew (薇子) 的大作中提到: 】
: 如题。


───────────────────────────────────────
作者 vivian         时间 Tue May  6 01:32:53 2003                            
───────────────────────────────────────
【 以下文字转载自 vivian 的信箱 】
【 原文由 Aphroditte@smth.edu.cn 所发表 】
发信人: sundew (薇子), 信区: Programming
标  题: Re: 急:请教从公历到农历的转换算法!
发信站: BBS 水木清华站 (Wed Nov 10 21:58:10 1999)



发信人: HIFI (~ZZZ), 信区: program
标  题: Re: 公历和农历的关系!
发信站: 交大兵马俑BBS站 (Sun Jul 11 23:26:28 1999), 转信
【 在 star (光明来到乐) 的大作中提到: 】
: 有这种算法吗?
: 从来没见过
: 有的话我也要一份
: 【 在 ZiXiM (浙客西蒙) 的大作中提到: 】
给你一个delphi的例程:
  (我也是抄的,算法就请自己分析了.)
  unit CNYear;
  interface
  uses sysutils;
  type TCNDate = Cardinal;
  function DecodeGregToCNDate(dtGreg:TDateTime):TCNDate;
  function GetGregDateFromCN(cnYear,cnMonth,cnDay:word;bLeap:Boolean=False):
TDateTime;
  function GregDateToCNStr(dtGreg:TDateTime):String;
  function isCNLeap(cnDate:TCNDate):boolean;
  implementation
  const cstDateOrg:Integer=32900; //公历1990-01-27的TDateTime表示 对应农历19


90-01-01
  const cstCNYearOrg=1990;
  const cstCNTable:array[cstCNYearOrg..cstCNYearOrg + 60] of WORD=(       //
   unsigned 16-bit
  24402, 3730, 3366, 13614, 2647, 35542, 858, 1749,           //1997
  23401, 1865, 1683, 19099, 1323, 2651, 10926, 1386,           //2005
  32213, 2980, 2889, 23891, 2709, 1325, 17757, 2741,           //2013
  39850, 1490, 3493, 61098, 3402, 3221, 19102, 1366,           //2021
  2773, 10970, 1746, 26469, 1829, 1611, 22103, 3243,           //2029
  1370, 13678, 2902, 48978, 2898, 2853, 60715, 2635,           //2037
  1195, 21179, 1453, 2922, 11690, 3474, 32421, 3365,           //2045
  2645, 55901, 1206, 1461, 14038);
             //2050
  //建表方法:
  // 0101 111101010010     高四位是闰月位置,后12位表示大小月,大月30天,小月29
天,
  //闰月一般算小月,但是有三个特例2017/06,2036/06,2047/05
  //对于特例则高四位的闰月位置表示法中的最高为设置为1 特殊处理用wLeapNormal变

  // //2017/06 28330->61098 2036/06 27947->60715 2047/05 23133->55901
  //如果希望用汇编,这里有一条信息:农历不会滞后公历2个月.
  //将公历转换为农历


  //返回:12位年份+4位月份+5位日期
  function DecodeGregToCNDate(dtGreg:TDateTime):TCNDate;
  var
    iDayLeave:Integer;
    wYear,wMonth,wDay:WORD;
    i,j:integer;
    wBigSmallDist,wLeap,wCount,wLeapShift:WORD;
  label OK;
  begin
    result := 0;
    iDayLeave := Trunc(dtGreg) - cstDateOrg;
    DecodeDate(IncMonth(dtGreg,-1),wYear,wMonth,wDay);
    if (iDayLeave < 0) or (iDayLeave > 22295 )then Exit;
                //Raise Exception.Create('目前只能算1990-01-27以后的');
                //Raise Exception.Create('目前只能算2051-02-11以前的');
    for i:=Low(cstCNTable)   to High(cstCNTable) do begin
        wBigSmallDist := cstCNTable[i];
        wLeap := wBigSmallDist shr 12;
        if wLeap > 12 then begin
            wLeap := wLeap and 7;
            wLeapShift := 1;
        end else


            wLeapShift := 0;
        for j:=1 to 12 do begin
            wCount:=(wBigSmallDist and 1) + 29;
            if j=wLeap then wCount := wCount - wLeapShift;
            if iDayLeave < wCount   then begin
                Result := (i shl 9) + (j shl 5) + iDayLeave + 1;
                Exit;
            end;
            iDayLeave := iDayLeave - wCount;
            if j=wLeap then begin
                wCount:=29 + wLeapShift;
                if iDayLeave < wCount   then begin
                    Result := (i shl 9) + (j shl 5) + iDayLeave + 1 + (1 shl
21);
                    Exit;
                end;
                iDayLeave := iDayLeave - wCount;
            end;
            wBigSmallDist := wBigSmallDist shr 1;
        end;
    end;
  //返回值:


  // 1位闰月标志 + 12位年份+4位月份+5位日期             (共22位)
  end;
  function isCNLeap(cnDate:TCNDate):boolean;
  begin
    result := (cnDate and $200000) <> 0;
  end;
  function GetGregDateFromCN(cnYear,cnMonth,cnDay:word;bLeap:Boolean=False):
TDateTime;
  var
    i,j:integer;
    DayCount:integer;
    wBigSmallDist,wLeap,wLeapShift:WORD;
  begin
    // 0101 010010101111     高四位是闰月位置,后12位表示大小月,大月30天,小月
29天,
    DayCount := 0;
    if (cnYear < 1990) or (cnYear >2050) then begin
        Result := 0;
        Exit;
    end;
    for i:= cstCNYearOrg to cnYear-1 do begin
          wBigSmallDist := cstCNTable[i];


          if (wBIgSmallDist and $F000) <> 0 then DayCount := DayCount + 29;
          DayCount := DayCount + 12 * 29;
          for j:= 1 to 12 do begin
              DayCount := DayCount + wBigSmallDist and 1;
              wBigSmallDist := wBigSmallDist shr 1;
          end;
    end;
    wBigSmallDist := cstCNTable[cnYear];
    wLeap := wBigSmallDist shr 12;
    if wLeap > 12 then begin
        wLeap := wLeap and 7;
        wLeapShift := 1;                       //大月在闰月.
    end else
        wLeapShift := 0;
    for j:= 1 to cnMonth-1 do begin
        DayCount:=DayCount + (wBigSmallDist and 1) + 29;
        if j=wLeap then DayCount := DayCount + 29;
        wBigSmallDist := wBigSmallDist shr 1;
    end;
    if bLeap and (cnMonth = wLeap)   then   //是要闰月的吗?
        DayCount := DayCount + 30 - wLeapShift;
    result := cstDateOrg + DayCount + cnDay - 1;


  end;
  //将日期显示成农历字符串.
  function GregDateToCNStr(dtGreg:TDateTime):String;
  const hzNumber:array[0..10] of string=('零','一','二','三','四','五','六',
'七','八','九','十');
  function ConvertYMD(Number:Word;YMD:Word):string;
  var
    wTmp:word;
  begin
    result := '';
    if YMD = 1 then begin //年份
        while Number > 0 do begin
            result := hzNumber[Number Mod 10] + result;
            Number := Number DIV 10;
        end;
        Exit;
    end;
    if Number<=10 then begin   //可只用1位
        if YMD = 2 then //月份
            result := hzNumber[Number]
        else                       //天
            result := '初' + hzNumber[Number];


        Exit;
    end;
    wTmp := Number Mod 10;   //个位
    if wTmp <> 0 then result := hzNumber[wTmp];
    wTmp := Number Div 10;           //十位
    result:='十'+result;
    if wTmp > 1 then   result := hzNumber[wTmp] + result;
  end;
  var
    cnYear,cnMonth,cnDay:word;
    cnDate:TCNDate;
    strLeap:string;
  begin
    cnDate:= DecodeGregToCNDate(dtGreg);
    if cnDate = 0 then begin
        result := '输入越界';
        Exit;
    end;
    cnDay := cnDate and $1F;
    cnMonth := (cnDate shr 5) and $F;
    cnYear := (cnDate shr 9) and $FFF;
    //测试第22位,为1表示闰月


    if isCNLeap(cnDate) then strLeap:='(闰)' else   strLeap := '';
    result := '农历' + ConvertYMD(cnYear,1) + '年' + ConvertYMD(cnMonth,2) +
'月'
                  + strLeap + ConvertYMD(cnDay,3) ;
  end;
  end.
───────────────────────────────────────
作者 vivian         时间 Tue May  6 01:33:01 2003                            
───────────────────────────────────────
【 以下文字转载自 vivian 的信箱 】
【 原文由 Aphroditte@smth.edu.cn 所发表 】
发信人: peach (呆呆), 信区: Programming
标  题: Re: 请问万年历的算法!!
发信站: BBS 水木清华站 (Fri Jun 14 19:22:10 2002)

最关键的是jdnum和initfromjd两个函数

如果想知道怎么回事,请查天文学上的儒略历


#ifndef _SPUTIL_TIME_H_INC_
#define _SPUTIL_TIME_H_INC_



//      4786    调试符号长度超过255个字符
//      4530    C++ Exception catch
#pragma warning(disable:4786 4530)

#include <sputil/sputildef.h>
#include <time.h>

nsbegin(spu);

class   time    {
private:

        //      year, month, day, seconds;
        spu::word       y;      // 1 ~ 65535
        spu::byte       m, d;   // m: 1 ~ 12, d: 1 ~ 31
        int             s;  // seconds in one day 0 ~ 86399
public:
        time () : y(1), m(1), d(1), s(0) {
        }
        time (int year, int month, int day, int seconds=0) : y(year), m(month),
d(day), s(seconds){


        };
        time (int jd, int seconds=0) : s(seconds){
                initfromjd(jd);
        }
        time (time_t tm) {
                s = tm%86400;
                initfromjd(2440588 + tm/86400);
        }
        time (__int64 i64) {
                i64/=10000000;
                i64 -= 11644473600;
                s = (int)(i64%86400);
                initfromjd(2440588 + (int)(i64/86400));
        }
#ifdef  _WIN32
        time (const FILETIME* pft) {
                __int64 i64 = *(__int64*)pft;
                i64/=10000000;
                i64 -= 11644473600;
                s = (int)(i64%86400);
                initfromjd(2440588 + (int)(i64/86400));
        }


        time (const SYSTEMTIME* pst) {
                y = pst->wYear;
                m = (spu::byte)pst->wMonth;
                d = (spu::byte)pst->wDay;
                s = pst->wHour*3600 + pst->wMinute*60 + pst->wSecond;
        }
        time (const FILETIME& ft) {
                *this = time(&ft);
        }
        time (const SYSTEMTIME& st) {
                *this = time(&st);
        }
#endif
        int             getyear ()      const {
                return y;
        }
        int             getmonth ()     const {
                return m;
        }
        int             getday ()       const {
                return d;
        }


        int             gethour ()      const {
                return s/3600;
        }
        int             getminute ()    const {
                return s%3600/60;
        }

        int             getsecond ()    const {
                return s%60;
        }

        int             gets () const {
                return s;
        }

        time_t  get_time_t () const {
                //      未作溢出检查
                return (jdnum () - 2440588)*86400 + s;
        }

        __int64 ftime() const {
                return (__int64)jdnum ()*86400+s;


        }

        int             dayofweek() const {
                return (jdnum ()+1)%7;
        }

        int             setyear (int year) {
                return y = year;
        }

        int             setmonth (int month) {
                return m = month;
        }

        int             setday (int day) {
                return d = day;
        }

        int             sethour (int h) {
                h %= 24;
                s = s%3600 + h *3600;
                return h;


        }

        int             setminute (int m) {
                m %= 60;
                s = s/3600*3600 + s%60 + m*60;
                return m;
        }

        int             setsecond (int sec) {
                sec %= 60;
                s = s/60*60 + sec;
                return s;
        }

        int             sets (int s) {
                this->s = s;
                return s;
        }

        int             jdnum () const {
                int             a = (m-14)/12;
                return   (1461*(y+4800+a))/4


                                + (367*(m-2-12*(a)))/12
                                - (3*((y+4900+a)/100))/4
                                + d-32075;
        }

        void    initfromjd (int jdnum) {
                int     i, j, l, n;

                l = jdnum + 68569;
                n = ( 4 * l ) / 146097;
                l = l - ( 146097 * n + 3 ) / 4;
                i = ( 4000 * ( l + 1 ) ) / 1461001;
                l = l - ( 1461 * i ) / 4 + 31;
                j = ( 80 * l ) / 2447;
                d = l - ( 2447 * j ) / 80;
                l = j / 11;
                m = j + 2 - ( 12 * l );
                y = 100 * ( n - 49 ) + i + l;
        }

        time&   add (int days, int seconds = 0) {
                s += seconds;


                while(s < 0){
                        s += 86400;
                        days --;
                };
                while(s >= 86400){
                        days += s/86400;
                        s       %= 86400;
                }
                initfromjd (jdnum () + days);
                return *this;
        }

        time&   operator += (int sec) {
                add(sec/86400, sec%86400);
                return *this;
        }
        time    operator + (int sec) const {
                return  time(*this) += sec;
        }
        time&   operator -= (int sec) {
                return operator += (-sec);
        }

板凳



        time    operator - (int sec) const {
                return time(*this) -= sec;
        }
        int             day_diff(const time& rhs) const {
                return jdnum() - rhs.jdnum();
        }

        __int64 second_diff(const time& rhs) const {
                return ftime() - rhs.ftime();
        }

        bool    operator == (const time& right) const{
                return y == right.y && m == right.m && d == right.d && s ==
right.s;
        }
        bool    operator < (const time& right)  const{
                if(y < right.y)
                        return true;
                else if(y > right.y)
                        return false;

                if(m < right.m)


                        return true;
                else if(m > right.m)
                        return false;

                if(d < right.d)
                        return true;
                else if(d > right.d)
                        return false;

                if(s < right.s)
                        return true;
                else
                        return false;
        }

#ifdef  _WIN32
        operator SYSTEMTIME()   const {
                SYSTEMTIME      st = {y, m, dayofweek(), d, s/3600, s%3600/60,
s%60, 0};
                return st;
        }
#endif



        static  bool    isdatevalid(int year, int month, int day){
                time    a(year, month, day);
                return a.getday() == day && a.getmonth() == month && a.getyear()
== year;
        }
};

#ifdef  _WIN32
template <class T>
bool operator == (const time& x, const T& y) {
        return x == time(y);
}
template <class T>
bool operator <  (const time& x, const T& y) {
        return x == time(y);
}
template <class T>
bool operator == (const T& x, const time& y) {
        return time(x) == y;
}
template <class T>


bool operator < (const T& x, const time& y) {
        return time(x) < y;
}
#endif

nsend(spu);
#endif

【 在 wasabi (──╥╨<(@) 的大作中提到: 】
: UNIX中,cal命令可以根据年和月,把该月的日历(包括星期)打印出来,
: 请问这个万年历的C语言算法是什么? 谢谢。


───────────────────────────────────────
作者 vivian         时间 Tue May  6 01:33:58 2003                            
───────────────────────────────────────
【 以下文字转载自 vivian 的信箱 】
【 原文由 Aphroditte@smth.edu.cn 所发表 】
发信人: laurince (delta€), 信区: Programming
标  题: Re: 请问万年历的算法!!
发信站: BBS 水木清华站 (Fri Jun 14 20:38:15 2002)




        给你个现成的, 还有各种节日

3 楼

<html>
<head>
<body>
<SCRIPT language=JavaScript>
<!--
/***********************************************************************
******
                                   日期资料
************************************************************************
*****/

var lunarInfo=new Array(
0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,
0x09ad0,0x055d2,
0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,
0x095b0,0x14977,
0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,
0x052f2,0x04970,
0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,


0x1c8d7,0x0c950,
0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,
0x0a950,0x0b557,
0x06ca0,0x0b550,0x15355,0x04da0,0x0a5d0,0x14573,0x052d0,0x0a9a8,
0x0e950,0x06aa0,
0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,
0x05b57,0x056a0,
0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,
0x0b5a0,0x195a6,
0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,
0x0ab60,0x09570,
0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,
0x096d5,0x092e0,
0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,
0x092d0,0x0cab5,
0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,
0x052b0,0x0a930,
0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,
0x0ea65,0x0d530,
0x05aa0,0x076a3,0x096d0,0x04bd7,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,
0x0d520,0x0dd45,
0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,


0x06d20,0x0ada0)

var solarMonth=new Array(31,28,31,30,31,30,31,31,30,31,30,31);
var Gan=new Array("甲","乙","丙","丁","戊","己","庚","辛","壬","癸");
var Zhi=new Array("子","丑","寅","卯","辰","巳","午","未","申","酉","戌
","亥");
var Animals=new Array("鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡
","狗","猪");
var solarTerm = new Array("小寒","大寒","立春","雨水","惊蛰","春分","清
明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露
","秋分","寒露","霜降","立冬","小雪","大雪","冬至")
var sTermInfo = new Array(0,21208,42467,63836,85337,107014,128867,
150921,173149,195551,218072,240693,263343,285989,308563,331033,353350,
375494,397447,419210,440795,462224,483532,504758)
var nStr1 = new Array('日','一','二','三','四','五','六','七','八','九
','十')
var nStr2 = new Array('初','十','廿','卅',' ')
var monthName = new Array("JAN","FEB","MAR","APR","MAY","JUN","JUL",
"AUG","SEP","OCT","NOV","DEC");

//国历节日 *表示放假日
var sFtv = new Array(


"0101*元旦",
"0214 情人节",
"0308 妇女节",
"0312 植树节",
"0315 消费者权益日",
"0317 St. Patrick's",
"0401 愚人节",
"0501*劳动节",
"0504 青年节",
"0512 护士节",
"0512 茵生日",
"0601 儿童节",
"0614 Flag Day",
"0701 建党节 香港回归日",
"0703 炎黄在线诞辰",
"0718 托普诞辰",
"0801 建军节",
"0808 父亲节",
"0909 毛泽东逝世纪念",
"0910 教师节",
"0928 孔子诞辰",
"1001*国庆节",


"1006 老人节",
"1015 My Birthday^_^",
"1024 联合国日",
"1111 Veteran's / Remembrance Day",
"1112 孙中山诞辰",
"1220 澳门回归纪念",
"1225 Christmas Day",
"1226 毛泽东诞辰")

//农历节日 *表示放假日
var lFtv = new Array(
"0101*春节",
"0115 元宵节",
"0505 端午节",
"0707 七夕情人节",
"0715 中元节",
"0815 中秋节",
"0909 重阳节",
"1208 腊八节",
"1224 小年",
"0100*除夕")



//某月的第几个星期几
var wFtv = new Array(
"0131 Martin Luther King Day",
"0231 President's Day",
"0520 母亲节",
"0530 Armed Forces Day",
"0531 Victoria Day",
"0716 合作节",
"0730 被奴役国家周",
"0811 Civic Holiday",
"0911 Labor Holiday",
"1021 Columbus Day",
"1144 Thanksgiving")


/***********************************************************************
******
                                      日期计算
************************************************************************
*****/

//====================================== 传回农历 y年的总天数


function lYearDays(y) {
   var i, sum = 348
   for(i=0x8000; i>0x8; i>>=1) sum += (lunarInfo[y-1900] & i)? 1: 0
   return(sum+leapDays(y))
}

//====================================== 传回农历 y年闰月的天数
function leapDays(y) {
   if(leapMonth(y))  return((lunarInfo[y-1900] & 0x10000)? 30: 29)
   else return(0)
}

//====================================== 传回农历 y年闰哪个月 1-12 , 没
闰传回 0
function leapMonth(y) {
   return(lunarInfo[y-1900] & 0xf)
}

//====================================== 传回农历 y年m月的总天数
function monthDays(y,m) {
   return( (lunarInfo[y-1900] & (0x10000>>m))? 30: 29 )
}



//====================================== 算出农历, 传入日期物件, 传回农
历日期物件
//                                       该物件属性有 .year .month .
day .isLeap .yearCyl .dayCyl .monCyl
function Lunar(objDate) {

   var i, leap=0, temp=0
   var baseDate = new Date(1900,0,31)
   var offset   = (objDate - baseDate)/86400000

   this.dayCyl = offset + 40
   this.monCyl = 14

   for(i=1900; i<2050 && offset>0; i++) {
      temp = lYearDays(i)
      offset -= temp
      this.monCyl += 12
   }

   if(offset<0) {
      offset += temp;


      i--;
      this.monCyl -= 12
   }

   this.year = i
   this.yearCyl = i-1864

   leap = leapMonth(i) //闰哪个月
   this.isLeap = false

   for(i=1; i<13 && offset>0; i++) {
      //闰月
      if(leap>0 && i==(leap+1) && this.isLeap==false)
         { --i; this.isLeap = true; temp = leapDays(this.year); }
      else
         { temp = monthDays(this.year, i); }

      //解除闰月
      if(this.isLeap==true && i==(leap+1)) this.isLeap = false

      offset -= temp
      if(this.isLeap == false) this.monCyl ++


   }

   if(offset==0 && leap>0 && i==leap+1)
      if(this.isLeap)
         { this.isLeap = false; }
      else
         { this.isLeap = true; --i; --this.monCyl;}

   if(offset<0){ offset += temp; --i; --this.monCyl; }

   this.month = i
   this.day = offset + 1
}

//==============================传回国历 y年某m+1月的天数
function solarDays(y,m) {
   if(m==1)
      return(((y%4 == 0) && (y%100 != 0) || (y%400 == 0))? 29: 28)
   else
      return(solarMonth[m])
}
//============================== 传入 offset 传回干支, 0=甲子


function cyclical(num) {
   return(Gan[num%10]+Zhi[num%12])
}

//============================== 月历属性
function calElement(sYear,sMonth,sDay,week,lYear,lMonth,lDay,isLeap,
cYear,cMonth,cDay) {

      this.isToday    = false;
      //国历
      this.sYear      = sYear;
      this.sMonth     = sMonth;
      this.sDay       = sDay;
      this.week       = week;
      //农历
      this.lYear      = lYear;
      this.lMonth     = lMonth;
      this.lDay       = lDay;
      this.isLeap     = isLeap;
      //干支
      this.cYear      = cYear;
      this.cMonth     = cMonth;


      this.cDay       = cDay;

      this.color      = '';

      this.lunarFestival = ''; //农历节日
      this.solarFestival = ''; //国历节日
      this.solarTerms    = ''; //节气

}

//===== 某年的第n个节气为几日(从0小寒起算)
function sTerm(y,n) {
   var offDate = new Date( ( 31556925974.7*(y-1900) + sTermInfo[n]*60000
  ) + Date.UTC(1900,0,6,2,5) )
   return(offDate.getUTCDate())
}

//============================== 传回月历物件 (y年,m+1月)
function calendar(y,m) {

   var sDObj, lDObj, lY, lM, lD=1, lL, lX=0, tmp1, tmp2
   var lDPOS = new Array(3)


   var n = 0
   var firstLM = 0

   sDObj = new Date(y,m,1)            //当月一日日期

   this.length    = solarDays(y,m)    //国历当月天数
   this.firstWeek = sDObj.getDay()    //国历当月1日星期几


   for(var i=0;i<this.length;i++) {

      if(lD>lX) {
         sDObj = new Date(y,m,i+1)    //当月一日日期
         lDObj = new Lunar(sDObj)     //农历
         lY    = lDObj.year           //农历年
         lM    = lDObj.month          //农历月
         lD    = lDObj.day            //农历日
         lL    = lDObj.isLeap         //农历是否闰月
         lX    = lL? leapDays(lY): monthDays(lY,lM) //农历当月最後一天

         if(n==0) firstLM = lM
         lDPOS[n++] = i-lD+1


      }

      //sYear,sMonth,sDay,week,
      //lYear,lMonth,lDay,isLeap,
      //cYear,cMonth,cDay
      this[i] = new calElement(y, m+1, i+1, nStr1[(i+this.
firstWeek)%7],
                               lY, lM, lD++, lL,
                               cyclical(lDObj.yearCyl) ,cyclical(lDObj.
monCyl), cyclical(lDObj.dayCyl++) )


      if((i+this.firstWeek)%7==0)   this[i].color = 'red'  //周日颜色
      if((i+this.firstWeek)%14==13) this[i].color = 'red'  //周休二日颜

   }

   //节气
   tmp1=sTerm(y,m*2  )-1
   tmp2=sTerm(y,m*2+1)-1
   this[tmp1].solarTerms = solarTerm[m*2]
   this[tmp2].solarTerms = solarTerm[m*2+1]


   if(m==3) this[tmp1].color = 'red' //清明颜色

   //国历节日
   for(i in sFtv)
      if(sFtv[i].match(/^(\d{2})(\d{2})([\s\*])(.+)$/))
         if(Number(RegExp.$1)==(m+1)) {
            this[Number(RegExp.$2)-1].solarFestival += RegExp.$4 + ' '
            if(RegExp.$3=='*') this[Number(RegExp.$2)-1].color = 'red'
         }

   //月周节日
   for(i in wFtv)
      if(wFtv[i].match(/^(\d{2})(\d)(\d)([\s\*])(.+)$/))
         if(Number(RegExp.$1)==(m+1)) {
            tmp1=Number(RegExp.$2)
            tmp2=Number(RegExp.$3)
            this[((this.firstWeek>tmp2)?7:0) + 7*(tmp1-1) + tmp2 -
this.firstWeek].solarFestival += RegExp.$5 + ' '
         }

   //农历节日
   for(i in lFtv)


      if(lFtv[i].match(/^(\d{2})(.{2})([\s\*])(.+)$/)) {
         tmp1=Number(RegExp.$1)-firstLM
         if(tmp1==-11) tmp1=1
         if(tmp1 >=0 && tmp1<n) {
            tmp2 = lDPOS[tmp1] + Number(RegExp.$2) -1
            if( tmp2 >= 0 && tmp2<this.length) {
               this[tmp2].lunarFestival += RegExp.$4 + ' '
               if(RegExp.$3=='*') this[tmp2].color = 'red'
            }
         }
      }

   //黑色星期五
   if((this.firstWeek+12)%7==5)
      this[12].solarFestival += '黑色星期五 '

   //今日
   if(y==tY && m==tM) this[tD-1].isToday = true;

}

//====================== 中文日期

4 楼



function cDay(d){
   var s;

   switch (d) {
      case 10:
         s = '初十'; break;
      case 20:
         s = '二十'; break;
         break;
      case 30:
         s = '三十'; break;
         break;
      default :
         s = nStr2[Math.floor(d/10)];
         s += nStr1[d%10];
   }
   return(s);
}

////////////////////////////////////////////////////////////////////////
///////



var cld;

function drawCld(SY,SM) {
   var i,sD,s,size;
   cld = new calendar(SY,SM);

   if(SY>1874 && SY<1909) yDisplay = '光绪' + (((SY-1874)==1)?'元':
SY-1874)
   if(SY>1908 && SY<1912) yDisplay = '宣统' + (((SY-1908)==1)?'元':
SY-1908)
   if(SY>1911 && SY<1950) yDisplay = '民国' + (((SY-1911)==1)?'元':
SY-1911)
//   if(SY>1949) yDisplay = '共和国' + (((SY-1949)==1)?'元':SY-1949)

  // GZ.innerHTML = yDisplay +'年 农历' + cyclical(SY-1900+36) + '年
&nbsp;&nbsp;【'+Animals[(SY-4)%12]+'】';

   if(SY>1949) yDisplay = ''

   GZ.innerHTML = yDisplay +' 农历' + cyclical(SY-1900+36) + '年 &nbsp;
&nbsp;【'+Animals[(SY-4)%12]+'】';



   YMBG.innerHTML = "&nbsp;" + SY + "<BR>&nbsp;" + monthName[SM];


   for(i=0;i<42;i++) {

      sObj=eval('SD'+ i);
      lObj=eval('LD'+ i);

      sObj.className = '';

      sD = i - cld.firstWeek;

      if(sD>-1 && sD<cld.length) { //日期内
         sObj.innerHTML = sD+1;

         if(cld[sD].isToday) sObj.className = 'todyaColor'; //今日颜色

         sObj.style.color = cld[sD].color; //国定假日颜色

         if(cld[sD].lDay==1) //显示农历月
            lObj.innerHTML = '<b>'+(cld[sD].isLeap?'闰':'') + cld[sD].
lMonth + '月' + (monthDays(cld[sD].lYear,cld[sD].lMonth)==29?'小':'大


')+'</b>';
         else //显示农历日
            lObj.innerHTML = cDay(cld[sD].lDay);

         s=cld[sD].lunarFestival;
         if(s.length>0) { //农历节日
            if(s.length>6) s = s.substr(0, 4)+'…';
            s = s.fontcolor('red');
         }
         else { //国历节日
            s=cld[sD].solarFestival;

            if(s.length>0) {
               size = (s.charCodeAt(0)>0 && s.charCodeAt(0)<128)?8:4;
               if(s.length>size+2) s = s.substr(0, size)+'…';
               s = s.fontcolor('blue');
            }
            else { //廿四节气
               s=cld[sD].solarTerms;
               if(s.length>0) s = s.fontcolor('limegreen');
            }
         }


         if(s.length>0) lObj.innerHTML = s;

      }
      else { //非日期
         sObj.innerHTML = '';
         lObj.innerHTML = '';
      }
   }
}

function changeLong()
{
var y,m,ly,lm,id,im,iy,yangy,yangm,deltm,miny,tt;
CLD.SY.selectedIndex=CLD.D1.selectedIndex;
CLD.SM.selectedIndex=CLD.D2.selectedIndex;
yangm=0;yangy=0;
tt=true;
while (tt)
{
yangm=0;yangy=0;
   changeCld();
     for(i=0;i<42;i++)


     {
        sD = i - cld.firstWeek;
        if(sD>-1 && sD<cld.length)
        { //日期内
         if ((cld[sD].lMonth==CLD.D2.selectedIndex+1)&&(cld[sD].
lYear==CLD.D1.selectedIndex+1900))
         {
     yangy=CLD.SY.selectedIndex+1900;  yangm=CLD.SM.selectedIndex ;
     tt=false;
     break;
     }
         }
     }
     if (!tt) break;

   pushBtm('MD');
   changeCld();

//   alert(CLD.SY.selectedIndex+" "+CLD.SM.selectedIndex);

     for(i=0;i<42;i++)
     {


        sD = i - cld.firstWeek;
        if(sD>-1 && sD<cld.length)
        { //日期内
         if ((cld[sD].lMonth==CLD.D2.selectedIndex+1)&&(cld[sD].
lYear==CLD.D1.selectedIndex+1900))
         {
     yangy=CLD.SY.selectedIndex+1900;  yangm=CLD.SM.selectedIndex ;
     tt=false;
     break;
     }
         }
     }
   break;
}
//  alert(yangy+" "+yangm);


//CLD.SY.selectedIndex=yangy;//-1900;
//pushBtm('YU');
//pushBtm('YD');
CLD.SM.selectedIndex=yangm;
pushBtm('MD');


pushBtm('MU');



}
//changeLong end

function changeCld() {
   var y,m;
   y=CLD.SY.selectedIndex+1900;
   m=CLD.SM.selectedIndex;
   drawCld(y,m);
}

function pushBtm(K) {
   switch (K){
      case 'YU' :
         if(CLD.SY.selectedIndex>0) CLD.SY.selectedIndex--;
         break;
      case 'YD' :
         if(CLD.SY.selectedIndex<149) CLD.SY.selectedIndex++;
         break;


   

5 楼

   case 'MU' :
         if(CLD.SM.selectedIndex>0) {
            CLD.SM.selectedIndex--;
         }

         else {
            CLD.SM.selectedIndex=11;
            if(CLD.SY.selectedIndex>0) CLD.SY.selectedIndex--;
         }
         break;
      case 'MD' :
         if(CLD.SM.selectedIndex<11) {
            CLD.SM.selectedIndex++;
         }

         else {
            CLD.SM.selectedIndex=0;
            if(CLD.SY.selectedIndex<149) CLD.SY.selectedIndex++;
         }
         break;
      default :
         CLD.SY.selectedIndex=tY-1900;


         CLD.SM.selectedIndex=tM;
   }
   changeCld();
}



var Today = new Date();
var tY = Today.getFullYear();
var tM = Today.getMonth();
var tD = Today.getDate();
////////////////////////////////////////////////////////////////////////
//////

var width = "130";
var offsetx = 2;
var offsety = 16;

var x = 0;
var y = 0;
var snow = 0;
var sw = 0;


var cnt = 0;

var dStyle;
document.onmousemove = mEvn;

//显示详细日期资料
function mOvr(v) {
   var s,festival;
   var sObj=eval('SD'+ v);
   var d=sObj.innerHTML-1;

      //sYear,sMonth,sDay,week,
      //lYear,lMonth,lDay,isLeap,
      //cYear,cMonth,cDay

   if(sObj.innerHTML!='') {

      sObj.style.cursor = 's-resize';

      if(cld[d].solarTerms == '' && cld[d].solarFestival == '' &&
cld[d].lunarFestival == '')
         festival = '';


      else
         festival = '<TABLE WIDTH=100% BORDER=0 CELLPADDING=2
CELLSPACING=0 BGCOLOR="#CCFFCC"><TR><TD>'+
         '<FONT COLOR="#000000" STYLE="font-size:9pt;">'+cld[d].
solarTerms + ' ' + cld[d].solarFestival + ' ' + cld[d].
lunarFestival+'</FONT></TD>'+
         '</TR></TABLE>';

      s= '<TABLE WIDTH="130" BORDER=0 CELLPADDING="2" CELLSPACING=0
BGCOLOR="#000066"><TR><TD>' +
         '<TABLE WIDTH=100% BORDER=0 CELLPADDING=0 CELLSPACING=0><TR><TD
ALIGN="right"><FONT COLOR="#ffffff" STYLE="font-size:9pt;">'+
         cld[d].sYear+' 年 '+cld[d].sMonth+' 月 '+cld[d].sDay+' 日<br>星
期'+cld[d].week+'<br>'+
         '<font color="violet">农历'+(cld[d].isLeap?'闰 ':' ')+cld[d].
lMonth+' 月 '+cld[d].lDay+' 日</font><br>'+
         '<font color="yellow">'+cld[d].cYear+'年 '+cld[d].cMonth+'月
'+cld[d].cDay + '日</font>'+
         '</FONT></TD></TR></TABLE>'+ festival +'</TD></TR></TABLE>';


      document.all["detail"].innerHTML = s;



    if (snow == 0) {
         dStyle.left = x+offsetx-(width/2);
         dStyle.top = y+offsety;
     dStyle.visibility = "visible";
     snow = 1;
    }
}
}

//清除详细日期资料
function mOut() {
if ( cnt >= 1 ) { sw = 0 }
if ( sw == 0 ) { snow = 0; dStyle.visibility = "hidden";}
else cnt++;
}

//取得位置
function mEvn() {
   x=event.x;
   y=event.y;
if (document.body.scrollLeft)


    {x=event.x+document.body.scrollLeft; y=event.y+document.body.
scrollTop;}
if (snow){
      dStyle.left = x+offsetx-(width/2)
      dStyle.top = y+offsety
}
}

////////////////////////////////////////////////////////////////////////
///


function tick() {
   var today
   today = new Date()
   Clock.innerHTML = today.toLocaleString().replace(/(年|月)/g, "/").
replace(/日/, "");
//   Clock.innerHTML = TimeAdd(today.toGMTString(), CLD.TZ.value)
   window.setTimeout("tick()", 1000);
}

function setCookie(name, value) {


var today = new Date()
var expires = new Date()
expires.setTime(today.getTime() + 1000*60*60*24*365)
document.cookie = name + "=" + escape(value) + "; expires=" + expires.
toGMTString()
}

function getCookie(Name) {
   var search = Name + "="
   if(document.cookie.length > 0) {
      offset = document.cookie.indexOf(search)
      if(offset != -1) {
         offset += search.length
         end = document.cookie.indexOf(";", offset)
         if(end == -1) end = document.cookie.length
         return unescape(document.cookie.substring(offset, end))
      }
      else return ""
   }
}

/////////////////////////////////////////////////////////



function initial() {
   dStyle = detail.style;
   CLD.SY.selectedIndex=tY-1900;
   CLD.SM.selectedIndex=tM;
   drawCld(tY,tM);

//   CLD.TZ.selectedIndex=getCookie("TZ");
//   changeTZ();
   tick();
}



//-->
</SCRIPT>

<STYLE>.todyaColor {
BACKGROUND-COLOR: aqua
}
</STYLE>



<META content="Microsoft FrontPage 4.0" name=GENERATOR></HEAD>
<BODY onload=initial()>
<SCRIPT language=JavaScript><!--
   if(navigator.appName == "Netscape" || parseInt(navigator.
appVersion) < 4)
   document.write("<h1>你的浏览器无法执行此程序。</h1>此程序在 IE4 以后
的版本才能执行!!")
//--></SCRIPT>

<DIV id=detail style="POSITION: absolute"></DIV>
<FORM name=CLD>
<div align="center">

<TABLE width="672" align="center" height="259" bordercolordark="#CC9900"
border="4" background="l11.gif">
  <CENTER>
<center>
  <TBODY>
  </center></center>
  <TR>
  <TD align=middle vAlign=top width="170" height="255">
  <div align="center">


    <center>
  <TABLE BORDER=1 COLSPAN=2 width="221">
  <CENTER>
    <center><FONT size=2
      style="FONT-SIZE: 9pt">
    <td width="209">
      <p align="center"><font style="font-size:10.8pt" color=RED>本地计
算机时间:</FONT></FONT><BR><FONT color=#000080 face=ARIAL
      id=Clock size=3 align="center"></FONT>
      <P><!--时区 *表示自动调整为日光节约时间-->
      </center>
   </CENTER>
   </TABLE>
  </center>
    </div>
    <div align="center">
      <center>
      <table border=1 height="1" width="16">
      <td height="1" width="255">
            <table width="212" height="1"><CENTER>
            <center>
      <FONT id=tSave


      style="COLOR: red; FONT-FAMILY: Wingdings; FONT-SIZE:
18pt"></FONT>
      <td height="1" width="152"><font size="2"><FONT style="FONT-SIZE:
9pt">
      <font color="#0000FF">公历</font>年</font><FONT color=#ffffff
            style="FONT-SIZE: 9pt"><SELECT name=SY
onchange=changeCld()
            style="FONT-SIZE: 9pt">
              <SCRIPT language=JavaScript><!--
            for(i=1900;i<2050;i++) document.write('<option>'+i)
            //--></SCRIPT>
            </SELECT> </FONT>月<FONT color=#ffffff
            style="FONT-SIZE: 9pt"><SELECT name=SM
onchange=changeCld()
            style="FONT-SIZE: 9pt">
              <SCRIPT language=JavaScript><!--
            for(i=1;i<13;i++) document.write('<option>'+i)
            //--></SCRIPT>
            </SELECT></FONT></font>
      <P><font size="2"><FONT style="FONT-SIZE: 9pt"><font
color="#0000FF">阴历</font>年</font><FONT color=#ffffff
            style="FONT-SIZE: 9pt"><SELECT name=D1


onchange=changeLong()
            style="FONT-SIZE: 9pt">
              <SCRIPT language=JavaScript><!--
            for(i=1900;i<2050;i++) document.write('<option>'+i)
            //--></SCRIPT>
            </SELECT> </FONT>月<FONT color=#ffffff
            style="FONT-SIZE: 9pt"><SELECT name=D2
onchange=changeLong()
            style="FONT-SIZE: 9pt">
              <SCRIPT language=JavaScript><!--
            for(i=1;i<13;i++) document.write('<option>'+i)
            //--></SCRIPT>
            </SELECT></FONT></font></P>
      <div align="center" style="width: 4; height: 1">
      </div>
      <td width="1" align="center" height="1">
      <BUTTON onclick="pushBtm('MU')"  style="FONT-SIZE: 9pt">月↑
</BUTTON>
      <BUTTON onclick="pushBtm('')" style="FONT-SIZE: 9pt">当月
</BUTTON>
      <BUTTON onclick="pushBtm('MD')"  style="FONT-SIZE: 9pt">月↓
</BUTTON>&nbsp;


      </td>
        </center></center>
<tr>
  <CENTER>
      <TD align=center vAlign=top width=152 height="1">
      <BUTTON onclick="pushBtm('YU')" style="FONT-SIZE: 9pt">年↑
</BUTTON>&nbsp;
      <BUTTON onclick="pushBtm('YD')" style="FONT-SIZE: 9pt">年↓
</BUTTON>&nbsp;
      </TD>
        </center>
      <td colspan=2 width="46" height="1">
          <p align="left"><INPUT onclick="javascript:window.close();"
style="FONT-SIZE: 9pt" type=button value=关闭></p>
      </td>

       </table>
  <CENTER>
        <table border="1" width="100%" height="1"
bordercolordark="#FFFFCC">
        <tr>
          <td width="100%" height="1"><font style="font-size:10.8pt"


color=#0>  &nbsp;
            阴历存在跨月情况,如果查找到的阴历月跨两个公历月,用<font
color=blue>[月↑][月↓]</font>翻动可以找到你想要的确切日期。
</font></td>
        </tr>
      </table>
      </CENTER>
      </table>
      </center>
    </div>
    <TD align=middle width="423" height="255">
      <DIV style="position: absolute; top: 31; z-index: -1; left: 270;
width: 347; height: 108">
        <p>
        <p>
        <p><FONT id=YMBG
      style="COLOR: #f0f0f0; FONT-FAMILY: 'Arial Black'; FONT-SIZE:
20pt">&nbsp;</FONT>
      </DIV>
      <div align="center">
      <center>
      <TABLE border=0 height="27" cellspacing="1">


        <TBODY>
        <TR>
          <TD bgColor=#000080 colSpan=7 align="center" height="24"><FONT
color=#000080 size=2
            style="FONT-SIZE: 9pt">月</FONT> <FONT color=#ffffff face=宋
体 id=GZ
            size=4></FONT><BR></TD></TR>
        <TR align=middle bgColor=#e0e0e0>
          <TD width=54 height="1" align="center" bgcolor="#99CCFF"><font
size="2">日</font></TD>
          <TD width=54 height="1" align="center" bgcolor="#99CCFF"><font
size="2">一</font></TD>
          <TD width=54 height="1" align="center" bgcolor="#99CCFF"><font
size="2">二</font></TD>
          <TD width=50 height="1" align="center" bgcolor="#99CCFF"><font
size="2">三</font></TD>
          <TD width=54 height="1" align="center" bgcolor="#99CCFF"><font
size="2">四</font></TD>
          <TD width=54 height="1" align="center" bgcolor="#99CCFF"><font
size="2">五</font></TD>
          <TD width=54 height="1" align="center" bgcolor="#99CCFF"><font
size="2">六</font></TD></TR>


        <SCRIPT language=JavaScript><!--
            var gNum
            for(i=0;i<6;i++) {
               document.write('<tr align=center>')
               for(j=0;j<7;j++) {
                  gNum = i*7+j
                  document.write('<td id="GD' + gNum +'"
onMouseOver="mOvr(' + gNum +')" onMouseOut="mOut()"><font id="SD' + gNum
+'" size=2 face="Arial Black"')
                  if(j == 0) document.write(' color=red')
                  if(j == 6)
                     if(i%2==1) document.write(' color=red')
                        else document.write(' color=green')
                  document.write(' TITLE=""> </font><br><font id="LD'
+ gNum + '" size=2 style="font-size:9pt"> </font></td>')
               }
               document.write('</tr>')
            }
            //--></SCRIPT>
        </TBODY></TABLE>
      </center>
      </div>


</TR></TBODY></TABLE>
</div>
</FORM>
</body>
</html>

6 楼

哗,版主很厉害啊,但是我看不明白啊!!!!!

7 楼

能不能简单点啊,太多了,好复杂哦!

8 楼

我要想大家帮忙找一个万年历程序设计
    要求程序可以:1:输出一年的日历
                  2:出连续多年的人历
选择1时,输入年号,输出相应日历,选择2时,输入起止年号,输出这几年的日历。
  我想要全过程。

9 楼

[font=楷体_GB2312][size=4][color=0000FF] 不会吧?怎么这么多人要万年历呀?晕了!!! [/font][/size][/color][em18]

10 楼

斑竹有水平啊!看得出你对编程很执著!

我来回复

您尚未登录,请登录后再回复。点此登录或注册