python年份天干地支代码_农历天干地支算法源代码大全(javascript、vbscript、C#、flash、C++、C等等【转】...

文章提供计算农历天干地支及当年属相的算法源程序,使用的语言为Javascript、VBScript、C#等。

一、C# 代码(1):

原来还准备自己写算法,并研究农历规则。发现那太难和麻烦了,光是农历的推算那就我等专门研究历法的人一下搞懂的。后来发现

。NET类库也提供一些基础的农历类System.Globalization.ChineseLunisolarCalendar。我改装了一下如DateTime时间形式。代码如

下。实现了 公历农历转换的功能。但是只能算到1900~2100年之间的。基本够日常使用了。源代码如下:

1.using System;

2.using System.Collections.Generic;

3.using System.Text;

4.5.namespace System

6.{

7.   8.    /// 中国常用农历日期时间类 9.    /// [email protected]   http://hi.csdn.net/zj53hao 10.

/// 11.    class ChinaDateTime

12.    {

13.        private int year, month, dayOfMonth;

14.        private bool isLeap;

15.        public DateTime time;

16.17.        18.        /// 获取当前日期的农历年 19.        /// 20.        public int

Year

21.        {

22.            get { return year; }

23.        }

24.25.        26.        /// 获取当前日期的农历月份 27.        /// 28.        public int

Month

29.        {

30.            get { return month; }

31.        }

32.33.        34.        /// 获取当前日期的农历月中天数 35.        /// 36.        public

int DayOfMonth

37.        {

38.            get { return dayOfMonth; }

39.        }

40.41.        42.        /// 获取当前日期是否为闰月中的日期 43.        /// 44.

public bool IsLeap

45.        {

46.            get { return isLeap; }

47.        }

48.49.        System.Globalization.ChineseLunisolarCalendar cc;

50.        51.        /// 返回指定公历日期的阴历时间 52.        /// 53.        ///

name="time"> 54.        public ChinaDateTime(DateTime time)

55.        {

56.            cc = new System.Globalization.ChineseLunisolarCalendar();

57.

58.             if (time > cc.MaxSupportedDateTime || time < cc.MinSupportedDateTime)

59.                throw new Exception("参数日期时间不在支持的范围内,支持范围:" +

cc.MinSupportedDateTime.ToShortDateString()+"到"+cc.MaxSupportedDateTime.ToShortDateString());

60.            year = cc.GetYear(time);

61.            month = cc.GetMonth(time);

62.            dayOfMonth = cc.GetDayOfMonth(time);

63.            isLeap = cc.IsLeapMonth(year, month);

64.            if (isLeap) month -= 1;

65.            this.time = time;

66.67.        }

68.69.        70.        /// 返回当前日前的农历日期。 71.        /// 72.        public

static ChinaDateTime Now

73.        {

74.            get { return new ChinaDateTime(DateTime.Now); }

75.        }

76.77.        78.        /// 返回指定农历年,月,日,是否为闰月的农历日期时间 79.        ///

80.        /// 81.        /// 82.        ///

83.        /// 84.        public ChinaDateTime(int

Year, int Month, int DayOfMonth, bool IsLeap)

85.        {

86.            if (Year >= cc.MaxSupportedDateTime.Year || Year <= cc.MinSupportedDateTime.Year)

87.                throw new Exception("参数年份时间不在支持的范围内,支持范围:" +

cc.MinSupportedDateTime.ToShortDateString() + "到" + cc.MaxSupportedDateTime.ToShortDateString());

88.89.            if (Month < 1 || Month > 12)

90.                throw new Exception("月份必须在1~12范围");

91.            cc = new System.Globalization.ChineseLunisolarCalendar();

92.

93.            if(cc.GetLeapMonth(Year)!=Month&&IsLeap)

94.                throw new Exception("指定的月份不是当年的闰月");

95.            if (cc.GetDaysInMonth(Year, IsLeap ? Month + 1 : Month) < DayOfMonth || DayOfMonth < 1)

96.                throw new Exception("指定的月中的天数不在当前月天数有效范围");

97.            year = Year;

98.            month = Month;

99.            dayOfMonth = DayOfMonth;

100.            isLeap = IsLeap;

101.            time = DateTime.Now;

102.        }

103.104.        105.        /// 获取当前农历日期的公历时间 106.        /// 107.

public DateTime ToDateTime()

108.        {

109.            return cc.ToDateTime(year, isLeap ? month + 1 : month, dayOfMonth, time.Hour, time.Minute,

time.Second, time.Millisecond);

110.        }

111.112.        113.        /// 获取指定农历时间对应的公历时间 114.        /// 115.

/// 116.        /// 117.        public static DateTime ToDateTime

(ChinaDateTime CnTime)

118.        {

119.            return CnTime.ToDateTime();

120.        }

121.122.        123.        /// 获取指定公历时间转换为农历时间 124.        /// 125.

/// 126.        /// 127.        public static ChinaDateTime

ToChinaDateTime(DateTime Time)

128.        {

129.            return new ChinaDateTime(Time);

130.        }

131.   }

132.}

二、C#代码(2):

1、农历类的使用

.net框架不支持直接将日期转换成农历格式的字符串,那么要将显示农历格式的日期,就只要自已写代码了。不过由于已经有了

ChineseLunisolarCalendar类实现了公历转换为农历日期的功能,所以要写这样的代码也比较简单。需要用到

ChineseLunisolarCalendar以下几个主要方法:

int GetYear (DateTime time) 获取指定公历日期的农历年份,使用的还是公历纪元。在每年的元旦之后春节之前农历的纪年会比公

历小1,其它时候等于公历纪年。虽然农历使用传说中的耶稣生日纪元似乎不太妥当,不过我们确实已经几十年没有实行一个更好的纪

年办法,也只有将就了。

int GetMonth (DateTime time) 获取指定公历日期的农历月份。这里要注意了,由于农历有接近三分之一的年份存在闰月,则在这

些年份里会有十三个,而具体哪一个月是闰月也说不准,这里不同于希伯来历。以今年为例,今年闰七月,则此方法在参数为闰七月

的日期是返回值为 8,参数为农历十二月的日期时返回值为13

bool IsLeapMonth ( int year,   int month) 获取指定农历年份和月份是否为闰月,这个函数和上个函数配合使用就可以算出农历

的月份了。

int GetDayOfMonth (DateTime time) 获取指定公历日期的农历天数,这个值根据大月或者小月取值是1到30或者1到29, MSDN上说的

1到31显然是错的, 没有哪个农历月份会有31天。

int GetSexagenaryYear (DateTime time) 获取指定公历日期的农历年份的干支纪年,从1到60,分别是甲子、乙丑、丙寅、….癸亥

, 比如戊戌变法、辛亥革命就是按这个来命名的。当然算八字也少不了这个。

int GetCelestialStem (int sexagenaryYear) 获取一个天支的天干, 从1到10, 表示甲、乙、丙….,说白了就是对10取模。

int GetTerrestrialBranch (int sexagenaryYear) ) 获取一个干支的地支,, 从1到12, 表示子、丑、寅、…今年是狗年,那么今

年年份的地支就是“戌”。

有了这几个方法,显示某天的农历月份日期、农历节日等都是小菜一碟,算命先生排八字用这几个方法,又快又准确,写出的代码也

很短。

2、几种东亚农历类的区别

经过我的测试,ChineseLunisolarCalendar, JapaneseLunisolarCalendar, KoreanLunisolaCalendarr, TaiwanLunisolarCalendar

这四种日历,无论哪一种,以2006年2月6日为参数,调用它们的GetMonth方法得到的结果都是1,GetDayOfMonth得到的结果都是8。

想想也是,我们过的端午节和韩国的不太可能不是一天。

但是调用GetYear方法得到结果就有区别了ChineseLunisolarCalendar和KoreanLunisolarCalendar都返回2006,也就是公历纪年,

TaiwanLunisolarCalendar的返回值是95,依然是民国纪年,JapaneseLunisolarCalendar的返回值是18, 平成纪年。

另外的一个区别是这四种日历的MinSupportedDateTime和MaxSupportedDateTime各不一样,以下是对照表:

日历类 MinSupportedDateTime MaxSupportedDateTime

ChineseLunisolarCalendar 公元1901年1月初1 公元2100年12月29

TaiwanLunisolarCalendar 民国1年1月初1 民国139年12月29

JapaneseLunisolarCalendar 昭和35年1月初1 平成61年12月29

KoreanLunisolarCalendar 公元918年1月初1 公元2050年12月29

韩国农历类支持的最小日期为918年(也即高丽王朝建立的年份),以此而论,中国农历类支持的最小日期不说从商周算起,从汉唐算

总该没问题吧?微软公司啊,又在“厚彼薄此”,唉。

其次,日本还以天皇纪年,如果哪天xxxx, 岂不是使用JapaneseLunisolarCalendar写出的程序都有问题啦?

3、写自已的日期格式化器

昨天看了一篇文章,说目前大家用的“农历”这个术语是文革时期才有的,目的是反封建。这里为了省事,还是继续使用这个术语。

而英文名称ChineseLunisolarCalendar太长,我自己的代码中就用ChineseCalendar为相关功能命名,这个名字也还过得去吧。

我原先设想自定义一个类,使得能写出这样的代码:

string s= DateTime.Now.ToString(new MyFormatProvider());

就能得出我想要的农历日期字符串,经过测试却失败了,依据我的分析,微软公司在.net框架中把日期时间型的格式写死了,只能依

据相关的地区采用固定的几种显示格式,没法再自行定义。而前文已经说过,而所有的相关格式微软公司都放到一个名为

culture.nlp的文件中(这个文件在以前的.net框架是一个独立的文件,在.net 2.0被作为一个资源编译到mscorlib.dll中。) (我的

这个不能为DateTime写自已的格式化器的观点没有资料佐证,如有不当之处,请大家指正)

虽然不能为DataTime写自定义的格式器,但还有另外一个途径,就是为String类的Format方法写自定义格式化器,我测试了一下,效

果还不错,调用方式如下:

string s= String.Format(new ChineseCalendarFormatter(), "{0:D}",DateTime.Now);

可以得到“二〇〇六年正月初九”

string s= String.Format(new ChineseCalendarFormatter(), "{0:d}",DateTime.Now);

可以得到“丙戌年正月初九”

虽然没有前面所设想的方便,但也还能接受,全部代码帖出如下:

第一个类,主要是封装了农历的一些常用字符和对日历处理的最基本功能

1.using System;

2.using System.Collections.Generic;

3.using System.Text;

4.5.using System.Globalization;

6.7.public static class ChineseCalendarHelper

8.{

9.    public static string GetYear(DateTime time)

10.    {

11.        StringBuilder sb = new StringBuilder();

12.        int year = calendar.GetYear(time);

13.        int d;

14.        do15.        {

16.            d = year % 10;

17.            sb.Insert(0, ChineseNumber[d]);

18.            year = year / 10;

19.        } while (year > 0);

20.        return sb.ToString();

21.    }

22.23.    public static string GetMonth(DateTime time)

24.    {

25.        int month = calendar.GetMonth(time);

26.        int year = calendar.GetYear(time);

27.        int leap = 0;

28.29.        //正月不可能闰月 30.        for (int i = 3; i <= month; i++)

31.        {

32.            if (calendar.IsLeapMonth(year, i))

33.            {

34.                leap = i;

35.                break;  //一年中最多有一个闰月 36.            }

37.38.        }

39.        if (leap > 0) month--;

40.        return (leap == month + 1 ? "闰" : "") + ChineseMonthName[month - 1];

41.    }

42.43.    public static string GetDay(DateTime time)

44.    {

45.        return ChineseDayName[calendar.GetDayOfMonth(time) - 1];

46.    }

47.48.    public static string GetStemBranch(DateTime time)

49.    {

50.        int sexagenaryYear = calendar.GetSexagenaryYear(time);

51.        string stemBranch = CelestialStem.Substring(sexagenaryYear % 10 - 1, 1) +

52.                      TerrestrialBranch.Substring(sexagenaryYear % 12 - 1, 1);

53.        return stemBranch;

54.    }

55.56.    private static ChineseLunisolarCalendar calendar = new ChineseLunisolarCalendar();

57.    private static string ChineseNumber = "〇一二三四五六七八九";

58.    public const string CelestialStem = "甲乙丙丁戊己庚辛壬癸";

59.    public const string TerrestrialBranch = "子丑寅卯辰巳午未申酉戌亥";

60.    public static readonly string[] ChineseDayName = new string[] {

61.            "初一","初二","初三","初四","初五","初六","初七","初八","初九","初十",

62.            "十一","十二","十三","十四","十五","十六","十七","十八","十九","二十",

63.            "廿一","廿二","廿三","廿四","廿五","廿六","廿七","廿八","廿九","三十"};

64.    public static readonly string[] ChineseMonthName = new string[]

65.           { "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" };

66.}

第二个类为自定义格式化器:

1.using System;

2.using System.Collections.Generic;

3.using System.Text;

4.5.using System.Globalization;

6.using System.Threading;

7.8.public class ChineseCalendarFormatter : IFormatProvider, ICustomFormatter

9.{

10.    //实现IFormatProvider 11.    public object GetFormat(Type formatType)

12.    {

13.        if (formatType == typeof(ICustomFormatter))

14.            return this;

15.        else16.            return Thread.CurrentThread.CurrentCulture.GetFormat(formatType);

17.    }

18.19.    //实现ICustomFormatter 20.    public string Format(string format, object arg, IFormatProvider

formatProvider)

21.    {

22.        string s;

23.        IFormattable formattable = arg as IFormattable;

24.        if (formattable == null)

25.            s = arg.ToString();

26.        else27.            s = formattable.ToString(format, formatProvider);

28.        if (arg.GetType() == typeof(DateTime))

29.        {

30.            DateTime time = (DateTime)arg;

31.            switch (format)

32.            {

33.                case "D": //长日期格式 34.                    s = String.Format("{0}年{1}月{2}",

35.                        ChineseCalendarHelper.GetYear(time),

36.                        ChineseCalendarHelper.GetMonth(time),

37.                        ChineseCalendarHelper.GetDay(time));

38.                    break;

39.                case "d": //短日期格式 40.                    s = String.Format("{0}年{1}月{2}",

ChineseCalendarHelper.GetStemBranch(time),

41.                        ChineseCalendarHelper.GetMonth(time),

42.                        ChineseCalendarHelper.GetDay(time));

43.                    break;

44.                case "M": //月日格式 45.                    s = String.Format("{0}月{1}",

ChineseCalendarHelper.GetMonth(time),

46.                        ChineseCalendarHelper.GetDay(time));

47.                    break;

48.                case "Y": //年月格式 49.                    s = String.Format("{0}年{1}月",

ChineseCalendarHelper.GetYear(time),

50.                        ChineseCalendarHelper.GetMonth(time));

51.                    break;

52.                default:

53.                    s = String.Format("{0}年{1}月{2}", ChineseCalendarHelper.GetYear(time),

54.                        ChineseCalendarHelper.GetMonth(time),

55.                        ChineseCalendarHelper.GetDay(time));

56.                    break;

57.            }

58.        }

59.        return s;

60.    }

61.}

这段代码中间处理格式那部份稍做改进,就可以支持更多的日期格式。

有了这两段代码为原型,要实现计算和显示一个日期的农历日期及其它功能,基本上就很容易了。

三、VBScript 代码:

1.

2.'Wonsoft, Welcome to visit my web http://wonsoft.cn

3.'***********************************************

4.' 类名称:ChinaDay

5.' 用途:

6.' 根据输入的日期计算该日期的农历天干地支及当年属相

7.' 使用方法:

8.' 第一个参数为输入参数,不填写默认为当日,

9.' 只计算1921-2-8之后的日期

10.' ##-------------------------------------------##

11.' Dim objChinaDay

12.' Dim sDay, sWeekDay, sChinaDay, sChinaYear,sChinaAni

13.' Set objChinaDay = New ChinaDay

14.' Call objChinaDay.Action("",sDay,sWeekDay,sChinaYear,sChinaDay,sChinaAni)

15.' Response.Write sDay&"
"

16.' Response.Write sWeekDay&"
"

17.' Response.Write sChinaYear&"
"

18.' Response.Write sChinaDay&"
"

19.' Response.Write sChinaAni&"
"

20.' ##-------------------------------------------##

21.' Copyright: 本代码非原创,是2001年收集的,原作者未知。

22.' License:Free

23.'*******************************************************

24.Class ChinaDay

25.26.Dim arrWeekName(7), MonthAdd(11), NongliData(99)

27.Dim arrTianGan(9), arrDiZhi(11), arrShuXiang(11), arrDayName(30), arrMonName(12)

28.Dim curTime, curYear, curMonth, curDay, curWeekday

29.Dim i, m, n, k, isEnd, bit, TheDate

30.31.'初始化数据

32.Sub Class_Initialize()

33.'---------------------------------------------------

34.'定义显示字串

35.36.'星期名

37.arrWeekName(0) = "*"

38.arrWeekName(1) = "星期日"

39.arrWeekName(2) = "星期一"

40.arrWeekName(3) = "星期二"

41.arrWeekName(4) = "星期三"

42.arrWeekName(5) = "星期四"

43.arrWeekName(6) = "星期五"

44.arrWeekName(7) = "星期六"

45.46.'天干名称

47.arrTianGan(0) = "甲"

48.arrTianGan(1) = "乙"

49.arrTianGan(2) = "丙"

50.arrTianGan(3) = "丁"

51.arrTianGan(4) = "戊"

52.arrTianGan(5) = "己"

53.arrTianGan(6) = "庚"

54.arrTianGan(7) = "辛"

55.arrTianGan(8) = "壬"

56.arrTianGan(9) = "癸"

57.58.'地支名称

59.arrDiZhi(0) = "子"

60.arrDiZhi(1) = "丑"

61.arrDiZhi(2) = "寅"

62.arrDiZhi(3) = "卯"

63.arrDiZhi(4) = "辰"

64.arrDiZhi(5) = "巳"

65.arrDiZhi(6) = "午"

66.arrDiZhi(7) = "未"

67.arrDiZhi(8) = "申"

68.arrDiZhi(9) = "酉"

69.arrDiZhi(10) = "戌"

70.arrDiZhi(11) = "亥"

71.72.'属相名称

73.arrShuXiang(0) = "鼠"

74.arrShuXiang(1) = "牛"

75.arrShuXiang(2) = "虎"

76.arrShuXiang(3) = "兔"

77.arrShuXiang(4) = "龙"

78.arrShuXiang(5) = "蛇"

79.arrShuXiang(6) = "马"

80.arrShuXiang(7) = "羊"

81.arrShuXiang(8) = "猴"

82.arrShuXiang(9) = "鸡"

83.arrShuXiang(10) = "狗"

84.arrShuXiang(11) = "猪"

85.86.'农历日期名

87.arrDayName(0) = "*"

88.arrDayName(1) = "初一"

89.arrDayName(2) = "初二"

90.arrDayName(3) = "初三"

91.arrDayName(4) = "初四"

92.arrDayName(5) = "初五"

93.arrDayName(6) = "初六"

94.arrDayName(7) = "初七"

95.arrDayName(8) = "初八"

96.arrDayName(9) = "初九"

97.arrDayName(10) = "初十"

98.arrDayName(11) = "十一"

99.arrDayName(12) = "十二"

100.arrDayName(13) = "十三"

101.arrDayName(14) = "十四"

102.arrDayName(15) = "十五"

103.arrDayName(16) = "十六"

104.arrDayName(17) = "十七"

105.arrDayName(18) = "十八"

106.arrDayName(19) = "十九"

107.arrDayName(20) = "二十"

108.arrDayName(21) = "廿一"

109.arrDayName(22) = "廿二"

110.arrDayName(23) = "廿三"

111.arrDayName(24) = "廿四"

112.arrDayName(25) = "廿五"

113.arrDayName(26) = "廿六"

114.arrDayName(27) = "廿七"

115.arrDayName(28) = "廿八"

116.arrDayName(29) = "廿九"

117.arrDayName(30) = "三十"

118.119.'农历月份名

120.arrMonName(0) = "*"

121.arrMonName(1) = "正"

122.arrMonName(2) = "二"

123.arrMonName(3) = "三"

124.arrMonName(4) = "四"

125.arrMonName(5) = "五"

126.arrMonName(6) = "六"

127.arrMonName(7) = "七"

128.arrMonName(8) = "八"

129.arrMonName(9) = "九"

130.arrMonName(10) = "十"

131.arrMonName(11) = "十一"

132.arrMonName(12) = "腊"

133.134.'---------------------------------------------------------

135.136.'公差数据定义

137.138.'公历每月前面的天数

139.MonthAdd(0) = 0

140.MonthAdd(1) = 31

141.MonthAdd(2) = 59

142.MonthAdd(3) = 90

143.MonthAdd(4) = 120

144.MonthAdd(5) = 151

145.MonthAdd(6) = 181

146.MonthAdd(7) = 212

147.MonthAdd(8) = 243

148.MonthAdd(9) = 273

149.MonthAdd(10) = 304

150.MonthAdd(11) = 334

151.152.'农历数据

153.NongliData(0) = 2635

154.NongliData(1) = 333387

155.NongliData(2) = 1701

156.NongliData(3) = 1748

157.NongliData(4) = 267701

158.NongliData(5) = 694

159.NongliData(6) = 2391

160.NongliData(7) = 133423

161.NongliData(8) = 1175

162.NongliData(9) = 396438

163.NongliData(10) = 3402

164.NongliData(11) = 3749

165.NongliData(12) = 331177

166.NongliData(13) = 1453

167.NongliData(14) = 694

168.NongliData(15) = 201326

169.NongliData(16) = 2350

170.NongliData(17) = 465197

171.NongliData(18) = 3221

172.NongliData(19) = 3402

173.NongliData(20) = 400202

174.NongliData(21) = 2901

175.NongliData(22) = 1386

176.NongliData(23) = 267611

177.NongliData(24) = 605

178.NongliData(25) = 2349

179.NongliData(26) = 137515

180.NongliData(27) = 2709

181.NongliData(28) = 464533

182.NongliData(29) = 1738

183.NongliData(30) = 2901

184.NongliData(31) = 330421

185.NongliData(32) = 1242

186.NongliData(33) = 2651

187.NongliData(34) = 199255

188.NongliData(35) = 1323

189.NongliData(36) = 529706

190.NongliData(37) = 3733

191.NongliData(38) = 1706

192.NongliData(39) = 398762

193.NongliData(40) = 2741

194.NongliData(41) = 1206

195.NongliData(42) = 267438

196.NongliData(43) = 2647

197.NongliData(44) = 1318

198.NongliData(45) = 204070

199.NongliData(46) = 3477

200.NongliData(47) = 461653

201.NongliData(48) = 1386

202.NongliData(49) = 2413

203.NongliData(50) = 330077

204.NongliData(5

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值