Bläddra i källkod

重构农历类ChineseCalendar

懒得勤快 7 år sedan
förälder
incheckning
f7803312d2

+ 3 - 3
Masuit.Tools.Core/Database/DataTableHelper.cs

@@ -4,7 +4,7 @@ using System.Collections.Generic;
 using System.Data;
 using System.Reflection;
 
-namespace Masuit.Tools.Database
+namespace Masuit.Tools.Core.Database
 {
     /// <summary>
     /// DataTable帮助类
@@ -373,9 +373,9 @@ namespace Masuit.Tools.Database
             if (dt.Rows.Count > 0)
             {
                 string tmp = "";
-                for (int i = 0; i < sorts.Length; i++)
+                foreach (var t in sorts)
                 {
-                    tmp += sorts[i] + ",";
+                    tmp += t + ",";
                 }
 
                 dt.DefaultView.Sort = tmp.TrimEnd(',');

+ 118 - 17
Masuit.Tools.Core/DateTimeExt/ChineseCalendar.cs

@@ -26,8 +26,16 @@ namespace Masuit.Tools.DateTimeExt
         private readonly int _cYear;
         private readonly int _cMonth;
         private readonly int _cDay;
-        private readonly bool _cIsLeapMonth; //当月是否闰月
-        private readonly bool _cIsLeapYear; //当年是否有闰月
+
+        /// <summary>
+        /// 当月是否闰月
+        /// </summary>
+        private readonly bool _cIsLeapMonth;
+
+        /// <summary>
+        /// 当年是否有闰月
+        /// </summary>
+        private readonly bool _cIsLeapYear;
 
         #endregion
 
@@ -36,7 +44,7 @@ namespace Masuit.Tools.DateTimeExt
         private const int MinYear = 1900;
         private const int MaxYear = 2050;
         private static readonly DateTime MinDay = new DateTime(1900, 1, 30);
-        private static readonly DateTime MaxDay = new DateTime(2069, 12, 31);
+        private static readonly DateTime MaxDay = new DateTime(2049, 12, 31);
         private const int GanZhiStartYear = 1864; //干支计算起始年
         private static readonly DateTime GanZhiStartDay = new DateTime(1899, 12, 22); //起始日
         private const string HzNum = "零一二三四五六七八九";
@@ -384,10 +392,21 @@ namespace Masuit.Tools.DateTimeExt
         #endregion
 
         #region 节日数据
+
         /// <summary>
-        /// 按公历计算的节
+        /// 自定义的工作
         /// </summary>
-        public static HashSet<DateInfoStruct> SolarHolidayInfo { get; } = new HashSet<DateInfoStruct>
+        public static HashSet<DateTime> CustomWorkDays { get; } = new HashSet<DateTime>();
+
+        /// <summary>
+        /// 自定义的节假日
+        /// </summary>
+        public static Dictionary<DateTime, string> CustomHolidays { get; } = new Dictionary<DateTime, string>();
+
+        /// <summary>
+        /// 按公历计算的通用节假日
+        /// </summary>
+        private static HashSet<DateInfoStruct> SolarHolidayInfo { get; } = new HashSet<DateInfoStruct>
         {
             new DateInfoStruct(1, 1, 1, "元旦"),
             new DateInfoStruct(2, 2, 0, "世界湿地日"),
@@ -439,9 +458,9 @@ namespace Masuit.Tools.DateTimeExt
         };
 
         /// <summary>
-        /// 按农历计算的节日
+        /// 按农历计算的通用
         /// </summary>
-        public static HashSet<DateInfoStruct> LunarHolidayInfo { get; } = new HashSet<DateInfoStruct>
+        private static HashSet<DateInfoStruct> LunarHolidayInfo { get; } = new HashSet<DateInfoStruct>
         {
             new DateInfoStruct(1, 1, 6, "春节"),
             new DateInfoStruct(1, 15, 0, "元宵节"),
@@ -456,10 +475,6 @@ namespace Masuit.Tools.DateTimeExt
             //new HolidayStruct(12, 30, 0, "除夕")  //注意除夕需要其它方法进行计算
         };
 
-        /// <summary>
-        /// 按农历计算的节日
-        /// </summary>
-        public static HashSet<DateTime> WorkDays { get; } = new HashSet<DateTime>();
 
         private static readonly WeekHolidayStruct[] WHolidayInfo =
         {
@@ -472,6 +487,7 @@ namespace Masuit.Tools.DateTimeExt
             new WeekHolidayStruct(10, 1, 4, "国际减轻自然灾害日"),
             new WeekHolidayStruct(11, 4, 5, "感恩节")
         };
+
         #endregion
 
         #endregion
@@ -887,7 +903,8 @@ namespace Masuit.Tools.DateTimeExt
 
                 foreach (DateInfoStruct lh in LunarHolidayInfo)
                 {
-                    if (lh.Month == _cMonth && (_cDay >= lh.Day || _cDay <= lh.Day + lh.Recess))
+                    var end = lh.Recess > 0 ? lh.Day + lh.Recess - 1 : lh.Day + lh.Recess;
+                    if (lh.Month == _cMonth && _cDay >= lh.Day && _cDay <= end)
                     {
                         tempStr = lh.HolidayName;
                         break;
@@ -943,11 +960,17 @@ namespace Masuit.Tools.DateTimeExt
                 string tempStr = "";
                 foreach (DateInfoStruct sh in SolarHolidayInfo)
                 {
-                    if ((sh.Month == _date.Month) && (_date.Day >= sh.Day || _date.Day <= sh.Day + sh.Recess))
+                    var end = sh.Recess > 0 ? sh.Day + sh.Recess - 1 : sh.Day + sh.Recess;
+                    if ((sh.Month == _date.Month) && _date.Day >= sh.Day && _date.Day <= end)
                     {
                         tempStr = sh.HolidayName;
                         break;
                     }
+                    if (CustomHolidays.Keys.Any(d => d.Date == _date))
+                    {
+                        tempStr = CustomHolidays[_date];
+                        break;
+                    }
                 }
 
                 return tempStr;
@@ -955,7 +978,54 @@ namespace Masuit.Tools.DateTimeExt
         }
 
         public bool IsHoliday => !IsWorkDay;
-        public bool IsWorkDay => string.IsNullOrEmpty(DateHoliday) && string.IsNullOrEmpty(ChineseCalendarHoliday) && !IsWeekend() || WorkDays.Any(s => s.Date == _date);
+
+        public bool IsWorkDay
+        {
+            get
+            {
+                bool isHoliday = false;
+                foreach (DateInfoStruct sh in SolarHolidayInfo)
+                {
+                    var end = sh.Recess > 0 ? sh.Day + sh.Recess - 1 : sh.Day + sh.Recess;
+                    if ((sh.Month == _date.Month) && _date.Day >= sh.Day && _date.Day <= end && sh.Recess > 0)
+                    {
+                        isHoliday = true;
+                        break;
+                    }
+
+                    if (CustomHolidays.Keys.Any(d => d.Date == _date))
+                    {
+                        isHoliday = true;
+                        break;
+                    }
+                }
+
+                if (!isHoliday)
+                {
+                    foreach (DateInfoStruct lh in LunarHolidayInfo)
+                    {
+                        var end = lh.Recess > 0 ? lh.Day + lh.Recess - 1 : lh.Day + lh.Recess;
+                        if (lh.Month == _cMonth && _cDay >= lh.Day && _cDay <= end && lh.Recess > 0)
+                        {
+                            isHoliday = true;
+                            break;
+                        }
+                    }
+
+                    //对除夕进行特别处理
+                    if (_cMonth == 12)
+                    {
+                        int i = GetChineseMonthDays(_cYear, 12); //计算当年农历12月的总天数
+                        if (_cDay == i) //如果为最后一天
+                        {
+                            isHoliday = true;
+                        }
+                    }
+                }
+
+                return !isHoliday && !IsWeekend() || CustomWorkDays.Any(s => s.Date == _date);
+            }
+        }
 
         /// <summary>
         /// 是否是周末
@@ -963,8 +1033,9 @@ namespace Masuit.Tools.DateTimeExt
         /// <returns></returns>
         private bool IsWeekend()
         {
-            return (_date.DayOfWeek == DayOfWeek.Saturday || _date.DayOfWeek == DayOfWeek.Sunday);
+            return _date.DayOfWeek == DayOfWeek.Saturday || _date.DayOfWeek == DayOfWeek.Sunday;
         }
+
         #endregion
 
         #region 公历日期
@@ -1128,10 +1199,10 @@ namespace Masuit.Tools.DateTimeExt
             {
                 if (_cIsLeapMonth)
                 {
-                    return "农历" + ChineseYearString + "闰" + ChineseMonthString + ChineseDayString;
+                    return ChineseYearString + "闰" + ChineseMonthString + ChineseDayString;
                 }
 
-                return "农历" + ChineseYearString + ChineseMonthString + ChineseDayString;
+                return ChineseYearString + ChineseMonthString + ChineseDayString;
             }
         }
 
@@ -1447,6 +1518,36 @@ namespace Masuit.Tools.DateTimeExt
             return new ChineseCalendar(nextDay);
         }
 
+        /// <summary>
+        /// 取下n天
+        /// </summary>
+        /// <returns></returns>
+        public ChineseCalendar AddWorkDays(int days)
+        {
+            var cc = new ChineseCalendar(_date);
+            while (true)
+            {
+                cc = cc.AddDays(1);
+                if (cc.IsWorkDay)
+                {
+                    days--;
+                }
+                else
+                {
+                    Console.WriteLine("阳历:" + cc.DateString);
+                    Console.WriteLine("节日:" + cc.DateHoliday);
+                    Console.WriteLine("农历节日:" + cc.ChineseCalendarHoliday);
+                    Console.WriteLine("星期:" + cc.WeekDayStr);
+                    Console.WriteLine("----------------------------");
+                }
+
+                if (days == 0)
+                {
+                    return cc;
+                }
+            }
+        }
+
         /// <summary>
         /// 加n月
         /// </summary>

+ 1 - 1
Masuit.Tools.Core/Masuit.Tools.Core.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>netcoreapp2.1</TargetFramework>
-    <Version>2.1.3.1</Version>
+    <Version>2.1.4</Version>
     <Authors>懒得勤快</Authors>
     <Company>masuit.com</Company>
     <Description>包含一些常用的操作类,大都是静态类,加密解密,反射操作,硬件信息,字符串扩展方法,日期时间扩展操作,大文件拷贝,图像裁剪,html处理,验证码、NoSql等常用封装。

+ 35 - 0
Masuit.Tools.UnitTest/ChineseCalendarTest.cs

@@ -0,0 +1,35 @@
+using Masuit.Tools.DateTimeExt;
+using System;
+using Xunit;
+
+namespace Masuit.Tools.UnitTest
+{
+    public class ChineseCalendarTest
+    {
+        [Fact]
+        public void GetChineseDateString_ReturnChineseDateString()
+        {
+            var cc = new ChineseCalendar(DateTime.Parse("2018-11-27"));
+            string actual = cc.ChineseDateString;
+            Assert.Equal("二零一八年十月二十", actual);
+        }
+
+        [Theory, InlineData("2018-11-27"), InlineData("2019-02-02")]
+        public void JudgeWorkDay_ReturnTrue(string date)
+        {
+            ChineseCalendar.CustomWorkDays.Add(DateTime.Parse("2019-02-02"));
+            var cc = new ChineseCalendar(DateTime.Parse(date));
+            var actual = cc.IsWorkDay;
+            Assert.True(actual);
+        }
+
+        [Fact]
+        public void JudgeHoliday_ReturnTrue()
+        {
+            ChineseCalendar.CustomHolidays.Add(DateTime.Parse("2019-2-6"), "春节");
+            var cc = new ChineseCalendar(DateTime.Parse("2019-2-6"));
+            var actual = cc.IsHoliday;
+            Assert.True(actual);
+        }
+    }
+}

+ 1 - 0
Masuit.Tools.UnitTest/Masuit.Tools.UnitTest.csproj

@@ -63,6 +63,7 @@
     </Reference>
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="ChineseCalendarTest.cs" />
     <Compile Include="ExtensionMethodsTest.cs" />
     <Compile Include="HtmlToolsTest.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />

+ 30 - 13
Masuit.Tools/DateTimeExt/ChineseCalendar.cs

@@ -394,9 +394,19 @@ namespace Masuit.Tools.DateTimeExt
         #region 节日数据
 
         /// <summary>
-        /// 按公历计算的节
+        /// 自定义的工作
         /// </summary>
-        public static HashSet<DateInfoStruct> SolarHolidayInfo { get; } = new HashSet<DateInfoStruct>
+        public static HashSet<DateTime> CustomWorkDays { get; } = new HashSet<DateTime>();
+
+        /// <summary>
+        /// 自定义的节假日
+        /// </summary>
+        public static Dictionary<DateTime, string> CustomHolidays { get; } = new Dictionary<DateTime, string>();
+
+        /// <summary>
+        /// 按公历计算的通用节假日
+        /// </summary>
+        private static HashSet<DateInfoStruct> SolarHolidayInfo { get; } = new HashSet<DateInfoStruct>
         {
             new DateInfoStruct(1, 1, 1, "元旦"),
             new DateInfoStruct(2, 2, 0, "世界湿地日"),
@@ -448,9 +458,9 @@ namespace Masuit.Tools.DateTimeExt
         };
 
         /// <summary>
-        /// 按农历计算的节日
+        /// 按农历计算的通用
         /// </summary>
-        public static HashSet<DateInfoStruct> LunarHolidayInfo { get; } = new HashSet<DateInfoStruct>
+        private static HashSet<DateInfoStruct> LunarHolidayInfo { get; } = new HashSet<DateInfoStruct>
         {
             new DateInfoStruct(1, 1, 6, "春节"),
             new DateInfoStruct(1, 15, 0, "元宵节"),
@@ -465,10 +475,6 @@ namespace Masuit.Tools.DateTimeExt
             //new HolidayStruct(12, 30, 0, "除夕")  //注意除夕需要其它方法进行计算
         };
 
-        /// <summary>
-        /// 按农历计算的节日
-        /// </summary>
-        public static HashSet<DateTime> WorkDays { get; } = new HashSet<DateTime>();
 
         private static readonly WeekHolidayStruct[] WHolidayInfo =
         {
@@ -960,6 +966,11 @@ namespace Masuit.Tools.DateTimeExt
                         tempStr = sh.HolidayName;
                         break;
                     }
+                    if (CustomHolidays.Keys.Any(d => d.Date == _date))
+                    {
+                        tempStr = CustomHolidays[_date];
+                        break;
+                    }
                 }
 
                 return tempStr;
@@ -981,6 +992,12 @@ namespace Masuit.Tools.DateTimeExt
                         isHoliday = true;
                         break;
                     }
+
+                    if (CustomHolidays.Keys.Any(d => d.Date == _date))
+                    {
+                        isHoliday = true;
+                        break;
+                    }
                 }
 
                 if (!isHoliday)
@@ -1006,7 +1023,7 @@ namespace Masuit.Tools.DateTimeExt
                     }
                 }
 
-                return !isHoliday && !IsWeekend() || WorkDays.Any(s => s.Date == _date);
+                return !isHoliday && !IsWeekend() || CustomWorkDays.Any(s => s.Date == _date);
             }
         }
 
@@ -1174,7 +1191,7 @@ namespace Masuit.Tools.DateTimeExt
         }
 
         /// <summary>
-        /// 取农历日期表示法:农历一九九七年正月初五
+        /// 取农历日期表示法:一九九七年正月初五
         /// </summary>
         public string ChineseDateString
         {
@@ -1182,10 +1199,10 @@ namespace Masuit.Tools.DateTimeExt
             {
                 if (_cIsLeapMonth)
                 {
-                    return "农历" + ChineseYearString + "闰" + ChineseMonthString + ChineseDayString;
+                    return ChineseYearString + "闰" + ChineseMonthString + ChineseDayString;
                 }
 
-                return "农历" + ChineseYearString + ChineseMonthString + ChineseDayString;
+                return ChineseYearString + ChineseMonthString + ChineseDayString;
             }
         }
 
@@ -1510,6 +1527,7 @@ namespace Masuit.Tools.DateTimeExt
             var cc = new ChineseCalendar(_date);
             while (true)
             {
+                cc = cc.AddDays(1);
                 if (cc.IsWorkDay)
                 {
                     days--;
@@ -1527,7 +1545,6 @@ namespace Masuit.Tools.DateTimeExt
                 {
                     return cc;
                 }
-                cc = cc.AddDays(1);
             }
         }
 

+ 2 - 2
Masuit.Tools/Properties/AssemblyInfo.cs

@@ -36,7 +36,7 @@ using System.Runtime.InteropServices;
 // 方法是按如下所示使用“*”: :
 // [assembly: AssemblyVersion("1.0.*")]
 
-[assembly: AssemblyVersion("2.1.3.1")]
-[assembly: AssemblyFileVersion("2.1.3.1")]
+[assembly: AssemblyVersion("2.1.4.0")]
+[assembly: AssemblyFileVersion("2.1.4.0")]
 [assembly: NeutralResourcesLanguage("zh-CN")]
 

+ 24 - 23
Test/Program.cs

@@ -7,30 +7,31 @@ namespace Test
     {
         static void Main(string[] args)
         {
-            //DateTime dt = DateTime.Parse("2019-2-6");
-            //ChineseCalendar.SolarHolidayInfo.Add(new DateInfoStruct(12, 31, 1, "元旦"));
-            //ChineseCalendar cc = new ChineseCalendar(dt);
-            //Console.WriteLine("阳历:" + cc.DateString);
-            //Console.WriteLine("属相:" + cc.AnimalString);
-            //Console.WriteLine("农历:" + cc.ChineseDateString);
-            //Console.WriteLine("时辰:" + cc.ChineseHour);
-            //Console.WriteLine("节气:" + cc.ChineseTwentyFourDay);
-            //Console.WriteLine("节日:" + cc.DateHoliday);
-            //Console.WriteLine("农历节日:" + cc.ChineseCalendarHoliday);
-            //Console.WriteLine("前一个节气:" + cc.ChineseTwentyFourPrevDay);
-            //Console.WriteLine("后一个节气:" + cc.ChineseTwentyFourNextDay);
-            //Console.WriteLine("干支:" + cc.GanZhiDateString);
-            //Console.WriteLine("星期:" + cc.WeekDayStr);
-            //Console.WriteLine("星宿:" + cc.ChineseConstellation);
-            //Console.WriteLine("星座:" + cc.Constellation);
-            //Console.WriteLine("是否是假期:" + cc.IsHoliday);
-            //Console.WriteLine("是否是工作日:" + cc.IsWorkDay);
+            DateTime dt = DateTime.Parse("2019-2-6");
+            ChineseCalendar cc = new ChineseCalendar(dt);
+            Console.WriteLine("阳历:" + cc.DateString);
+            Console.WriteLine("属相:" + cc.AnimalString);
+            Console.WriteLine("农历:" + cc.ChineseDateString);
+            Console.WriteLine("时辰:" + cc.ChineseHour);
+            Console.WriteLine("节气:" + cc.ChineseTwentyFourDay);
+            Console.WriteLine("节日:" + cc.DateHoliday);
+            Console.WriteLine("农历节日:" + cc.ChineseCalendarHoliday);
+            Console.WriteLine("前一个节气:" + cc.ChineseTwentyFourPrevDay);
+            Console.WriteLine("后一个节气:" + cc.ChineseTwentyFourNextDay);
+            Console.WriteLine("干支:" + cc.GanZhiDateString);
+            Console.WriteLine("星期:" + cc.WeekDayStr);
+            Console.WriteLine("星宿:" + cc.ChineseConstellation);
+            Console.WriteLine("星座:" + cc.Constellation);
+            Console.WriteLine("是否是假期:" + cc.IsHoliday);
+            Console.WriteLine("是否是工作日:" + cc.IsWorkDay);
 
-            DateTime today = DateTime.Parse("2019-1-1");
-            var cc = new ChineseCalendar(today);
-            var ccEnd = cc.AddWorkDays(30);
-            var endDate = ccEnd.Date;
-            Console.WriteLine((endDate - today).TotalDays);
+            //DateTime today = DateTime.Parse("2019-1-31");
+            //ChineseCalendar.CustomWorkDays.Add(DateTime.Parse("2019-02-02"));
+            //ChineseCalendar.CustomWorkDays.Add(DateTime.Parse("2019-02-03"));
+            //var cc = new ChineseCalendar(today);
+            //var ccEnd = cc.AddWorkDays(4);
+            //var endDate = ccEnd.Date;
+            //Console.WriteLine(endDate);
         }
     }