python年份天⼲地⽀代码_农历天⼲地⽀算法源代码⼤全
(javascript、vbscr。。。
⽂章提供计算农历天⼲地⽀及当年属相的算法源程序,使⽤的语⾔为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.{
/// 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; }
python和vb的代码可以通用吗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、农历类的使⽤
框架不⽀持直接将⽇期转换成农历格式的字符串,那么要将显⽰农历格式的⽇期,就只要⾃已写代码了。不过由于已经有了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());
就能得出我想要的农历⽇期字符串,经过测试却失败了,依据我的分析,微软公司在框架中把⽇期时间型的格式写死了,只能依
据相关的地区采⽤固定的⼏种显⽰格式,没法再⾃⾏定义。⽽前⽂已经说过,⽽所有的相关格式微软公司都放到⼀个名为
culture.nlp的⽂件中(这个⽂件在以前的框架是⼀个独⽴的⽂件,在 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]);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论