近期在做一个工作日历,想在日历上设置工作日,显示请假、加班等相关信息,显示农历日期信息(包括农历日期、节日

、节气)、公历信息(节假期)。

不能不说,http://www.cnblogs.com/hocylan/archive/2007/11/16/961218.html 这篇博文对我的帮助良多。但是

我也发现了一些问题。包括几下3个点:

首先,就是"0100 除夕"这个节日并不能被显示出来,无论是对于农历12月29是一年最后一天,还是12月30是最后一天。

我的解决方法是将这条数据改为"1230 除夕",然后在获取农历节日信息的时候判断这天和下一天的农历日期的年份是否相等,

如果不等,如一个是2012,一个是2013,那么这天就是“除夕”了。

其次,在判断几月的第几周的周几为某个节日时,

if (Convert.ToInt32(s[1]) == month && Convert.ToInt32(s[2]) == num && Convert.ToInt32(s[2]) == week)
这句应该改成:
if (Convert.ToInt32(s[1]) == month && Convert.ToInt32(s[2]) == num && Convert.ToInt32(s[3]) == week)。

博主可能疏忽了。

最后,我想在提到的这篇博文的基础上补充关于24节气的显示。

    节气指二十四时节和气候,是中国古代发明的一种用来指导农事的历法。中国古代利用土圭实测日晷,
将每年日影最长定为日至(又称日长至、长至、夏至),日影最短为日短至(又称短至、冬至),在春秋两季
各有一天的昼夜时间长短相等,便定为春分和秋分,在商朝时只有四个节气,到了周朝时发展到了八个,
直到西汉时才成为了现在的二十四节气。在史记太史公自序中就有提到阴阳、四时、八位、十二度、二十
四节气的概念。
二十四节气每一个分别相应于太阳在黄道上每运动15°所到达的一定位置。二十四节气又分为12个中气
和12个节气,一一相间。二十四节气反映了太阳的周年视运动,所以在公历中它们的日期是基本固定的,
上半年的节气在6日,中气在21日,下半年的节气在8日,中气在23日,二者前后不差1~2日。将一回归年
的长度等分成24份,从冬至开始,等间隔地依次相同安排各个中气和节气。这种方法叫做平气。由于太阳周
年视运动不均匀,按太阳黄经每移行15°的节气是非等间距的,此法称为定气。定气使用于历法计算中。因
为两个节气的时间长于一个朔望月(见月)的时间,所以可能出现一个月内只有一个节气或一个中气的情况。
从西汉的《太初历》起,规定遇到没有中气的月份定为上月的闰月。这种置闰原则沿用至今。
二十四节气的命名反应了季节、气侯现象、气侯变化三种。反应季节的是立春、春分、立夏、夏至、立
秋、秋分、立冬、冬至,又称八位; 反应气侯现象的是惊蛰、清明、小满、芒种; 反应气侯变化的有雨水、
谷雨、小暑、大暑、处暑、白露、寒露、霜降、小雪、大雪、小寒、大寒。
现代人根据太阳在黄道上的位置,准确地确定了二十四节气的具体时间。 节气的具体时间甚至精确到了几时几分,为了避免不同时间点显示的节气不同,我把节气的时间精确到天而已。
代码如下:

/// <summary>
        /// 计算某一年的节气,返回节气
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        private string ComputeSolarTerm(DateTime dt)
        {
            List<string> solar = new List<string>();
            int year = dt.Year;
            for (int month = 1; month < 13; month++)
            {

for (int n = month * 2 - 1; n <= month * 2; n++)
                {
                    double Termdays = Term(year, n, true);
                    double mdays = AntiDayDifference(year, Math.Floor(Termdays));
                    double sm1 = Math.Floor(mdays / 100);
                    int hour = (int)Math.Floor((double)Tail(Termdays) * 24);
                    int minute = (int)Math.Floor((double)(Tail(Termdays) * 24 - hour) * 60);
                    int tMonth = (int)Math.Ceiling((double)n / 2);
                    int day = (int)mdays % 100;
                    string jqtime = Convert.ToString(new DateTime(year, tMonth, day, hour, minute, 0).ToString("yyyyMMdd")); //这里把节气的日期精确到天
                    string jqname = solarTerm[n - 1];

solar.Add(jqtime+" "+jqname);
                }
            }

string str = @"(\d{4})(\d{2})(\d{2})([\s\*])(.+)$";     //匹配的正则表达式
            System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex(str);
            for (int i = 0; i < solar.Count;i++ )
            {
                string[] s = re.Split(solar[i]);
                if (Convert.ToInt32(s[1]) == dt.Year && Convert.ToInt32(s[2]) == dt.Month && Convert.ToInt32(s[3]) == dt.Day)
                {
                    return s[5];
                }
            }
            return "";
        }

#region 节气计算中用到的方法
        /// <summary>
        /// 返回y年第n个节气(如小寒为1)的日差天数值(pd取值真假,分别表示平气和定气)
        /// </summary>
        /// <param name="y"></param>
        /// <param name="n"></param>
        /// <param name="pd"></param>
        /// <returns></returns>
        private double Term(int y, int n, bool pd)
        {
            //儒略日
            double juD = y * (365.2423112 - 6.4e-14 * (y - 100) * (y - 100) - 3.047e-8 * (y - 100)) + 15.218427 * n + 1721050.71301;

//角度
            double tht = 3e-4 * y - 0.372781384 - 0.2617913325 * n;

//年差实均数
            double yrD = (1.945 * Math.Sin(tht) - 0.01206 * Math.Sin(2 * tht)) * (1.048994 - 2.583e-5 * y);

//朔差实均数
            double shuoD = -18e-4 * Math.Sin(2.313908653 * y - 0.439822951 - 3.0443 * n);

double vs = (pd) ? (juD + yrD + shuoD - EquivalentStandardDay(y, 1, 0) - 1721425) : (juD - EquivalentStandardDay(y, 1, 0) - 1721425);
            return vs;
        }
        /// <summary>
        /// 返回阳历y年日差天数为x时所对应的月日数(如y=2000,x=274时,返回1001(表示10月1日,即返回100*m+d))
        /// </summary>
        /// <param name="y"></param>
        /// <param name="x"></param>
        /// <returns></returns>
        private double AntiDayDifference(int y, double x)
        {
            int m = 1;
            for (int j = 1; j <= 12; j++)
            {
                int mL = DayDifference(y, j + 1, 1) - DayDifference(y, j, 1);
                if (x <= mL || j == 12)
                {
                    m = j;
                    break;
                }
                else
                    x -= mL;
            }
            return 100 * m + x;
        }
        /// <summary>
        /// 返回x的小数尾数,若x为负值,则是1-小数尾数
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        private double Tail(double x)
        {
            return x - Math.Floor(x);
        }
        /// <summary>
        /// 返回等效标准天数(y年m月d日相应历种的1年1月1日的等效(即对Gregorian历与Julian历是统一的)天数)
        /// </summary>
        /// <param name="y"></param>
        /// <param name="m"></param>
        /// <param name="d"></param>
        /// <returns></returns>
        private double EquivalentStandardDay(int y, int m, int d)
        {
            //Julian的等效标准天数
            double v = (y - 1) * 365 + Math.Floor((double)((y - 1) / 4)) + DayDifference(y, m, d) - 2;

if (y > 1582)
            {//Gregorian的等效标准天数
                v += -Math.Floor((double)((y - 1) / 100)) + Math.Floor((double)((y - 1) / 400)) + 2;
            }
            return v;
        }
        /// <summary>
        /// 返回阳历y年m月d日的日差天数(在y年年内所走过的天数,如2000年3月1日为61)
        /// </summary>
        /// <param name="y"></param>
        /// <param name="m"></param>
        /// <param name="d"></param>
        /// <returns></returns>
        private int DayDifference(int y, int m, int d)
        {
            int ifG = IfGregorian(y, m, d, 1);
            int[] monL = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
            if (ifG == 1)
                if ((y % 100 != 0 && y % 4 == 0) || (y % 400 == 0))
                    monL[2] += 1;
                else
                    if (y % 4 == 0)
                        monL[2] += 1;
            int v = 0;
            for (int i = 0; i <= m - 1; i++)
            {
                v += monL[i];
            }
            v += d;
            if (y == 1582)
            {
                if (ifG == 1)
                    v -= 10;
                if (ifG == -1)
                    v = 0;  //infinity
            }
            return v;
        }

// 判断y年m月(1,2,..,12,下同)d日是Gregorian历还是Julian历
        //(opt=1,2,3分别表示标准日历,Gregorge历和Julian历),是则返回1,是Julian历则返回0,
        // 若是Gregorge历所删去的那10天则返回-1
        private int IfGregorian(int y, int m, int d, int opt)
        {
            if (opt == 1)
            {
                if (y > 1582 || (y == 1582 && m > 10) || (y == 1582 && m == 10 && d > 14))
                    return (1);     //Gregorian
                else
                    if (y == 1582 && m == 10 && d >= 5 && d <= 14)
                        return (-1);  //空
                    else
                        return (0);  //Julian
            }

if (opt == 2)
                return (1);     //Gregorian
            if (opt == 3)
                return (0);     //Julian
            return (-1);
        }
        #endregion

C#日历上显示节气、阴阳历节假日信息的更多相关文章

  1. iOS:实现MKAnnotation协议,在地图上设置大头针,点击显示具体的位置信息

    如何添加大头针(地标): 通过MapView的addAnnotation方法可以添加一个大头针到地图上 通过MapView的addAnnotations方法可以添加多个大头针到地图上 –(void)a ...

  2. win10+Android(华为)系统原生日历同步方案+Sol日历桌面显示

    前言:本文是参考了其他博客基础上,新增了Android的免费桌面[月试图显示]功能.以及适配于上海交通大学的Canvas教学日历.方便进行多设备同步的日历管理.任务提醒. 目录 1.效果展示 2.方案 ...

  3. 某项目 需要在UITabbar 上显示小红点,在此搜罗了三个方法。

    1.使用系统自带的,并且可以在小红点上显示数字. [itemOne setBadgeValue:@""]; //显示不带数字的小红点 [itemOne setBadgeValue: ...

  4. 在饼图上显示百分比值(报表生成器和 SSRS)

    在饼图上显示百分比值(报表生成器和 SSRS) 默认情况下,图例中显示了类别来标识每个值. 如果使用了类别标签标记饼图,则可能希望在图例中显示百分比. 注意 在 SQL Server Data Too ...

  5. 8位灰度图在LCD上显示

    一.概述 1.灰度 灰度使用黑色调表示物体,即用黑色为基准色,不同的饱和度的黑色来显示图像.每个灰度对象都具有从 0%(白色)到灰度条100%(黑色)的亮度值. 使用黑白或灰度扫描仪生成的图像通常以灰 ...

  6. Winform之跨线程访问控件(在进度条上显示字体)

    此文章对于遇到必须使用线程但是没有办法在线程内操作控件的问题的处理  有很好的解决方案(个人认为的.有更好的方案欢迎交流.) 在做跨线程访问之前我们先了解下我们所做的需要达到的效果: 这个是批量的将x ...

  7. 日历上添加活动通知(Asp.net)

    <div id="calendar_contain"> </div> <script language="javascript" ...

  8. 使用Ajax+jQuery来实现前端收到的数据在console上显示+简单的主页设计与bootstrap插件实现图片轮播

    1.实现前端输入的数据在console上显示 上一篇是解决了在前端的输入信息在cygwin上显示,这次要给前台们能看见的数据,因为数据库里插入的数据少,所以写的语句翻来覆去就那几个词,emmm···当 ...

  9. c# Windows Service 桌面上显示UI

    介绍 本文的目的是说明如何从Windows Vista中的服务正确启动交互式进程,以及演示如何以完全管理员权限启动该进程.交互式过程是能够在桌面上显示UI的过程. 本文介绍如何创建一个名为Loader ...

随机推荐

  1. POJ 1584 A Round Peg in a Ground Hole 判断凸多边形,判断点在凸多边形内

    A Round Peg in a Ground Hole Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5456   Acc ...

  2. .net框架介绍

    .net 一般指 .net Framework框架,是一种平台,一种技术 C# 是一种编程语言,可以开发基于.net平台的应用 Java 既是一种技术,也是一种语言 .net可以开发桌面应用程序    ...

  3. JavaScript自动关闭窗口

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. Java POI 两种导出方式

    这里面包含了模板导出方法和自定义模板进行导出 package jp.co.syspro.poo.action.hibikoyou; import java.io.ByteArrayOutputStre ...

  5. MemCachedClient数据写入的三个方法

    set方法 1 将数据保存到cache服务器,如果保存成功则返回true 2 如果cache服务器存在同样的key,则替换之 3 set有5个重载方法,key和value是必须的参数,还有过期时间,h ...

  6. [置顶] VS自带工具:dumpbin的使用

    有时候我们想查看一个exe引用了哪些动态库,或者我们想看某个动态库包含哪些接口函数,这个时候可以使用dumpbin.exe工具: 1.输入Dumpbin -imports calldll.exe查看它 ...

  7. MySQL数据库中,使用游标循环遍历

    /*对*dt库下的所有数据表删除docuemttype为空和documenttype为MD,PD,ET的数据:delete from 表名 where length(documenttype)< ...

  8. 015_xml_函数

    015_xml_函数 --环境准备******************************************************************* USE test --f:/t ...

  9. iOS开发之通知中心(NSNotificationCenter)

    前言 面向对象的设计思想是把行为方法封装到每一个对象中,以用来增加代码的复用性.正是这种分散封装,增加了对象之间的相互关联,总是有很多的对象需要彼此了解以及相互操作! 一个简单示例说明这种交互产生的对 ...

  10. Xcode7 通过 Single View Application 得到一个 Empty Application 工程

    方法: 创建一个 Empty Application 工程 下面还是详细的说一下通过一个 Single View Application 工程得到一个 Empty Application 工程的方法: ...