C#实现工作日的计算

2021-05-01 09:27

阅读:474

标签:公司   abs   source   对象   json   没有   默认   param   why   

  早就萌生了写博客的想法,一直到现在才动手,原因有多方面,归根结底就是一个字~懒。

  今天无意看到一片博文,觉得里面说得几点原因很对,原文地址:我们为什么应该坚持写博客,感谢作者,让我有动力写了这篇博文。其实写博文是想记录自己遇到的一些问题的解决思路,方便以后查阅,同时希望可以跟大家一起交流提高。

  先介绍下本人的基本情况,本人今年刚毕业,坐标上海,.NET 菜鸟一枚,第一次写博客,有意见欢迎大家提出,大神轻喷!

 

  好了,废话不多说,开门见山。

  

一、开发背景:

  最近在公司开发的系统中,需要计算工作日,就是给出一个采购周期(n天),我需要计算出在n个工作日之后的日期。开始准备去调接口(ps:找了半天发现没有太合适的,还有吐槽下国家政府单位都没有官方接口的),但是负责这个项目的大佬说,万一别个的接口崩了,会影响我们自己的系统的正常运行,自己开发还是稳点,我就写了这个功能,特此记录下实现这个功能的思路。

二、定义:

  工作日想必大家都知道,就是除去周末和每年国务院颁布的节假日放假安排(例如:2017年部分节假日安排),其他就都是工作日(对了,差点忘记补班,这也算是工作日哦)。

三、实践:

  “废话”说的够多了,下面撸起袖子开干吧,代码都写了注释。

  提供了两个公共方法,先给大家看下简单测试的运行结果:

    (1).根据传入的工作日天数,获得计算后的日期

    技术分享

    (2).根据传入的时间,计算工作日天数;

    技术分享

  具体代码:

技术分享技术分享
  1 public class HolidayHelper
  2 {
  3     #region 字段属性
  4     private static object _syncObj = new object();
  5     private static HolidayHelper _instance { get; set; }
  6     private HolidayHelper() { }
  7     private static List cacheDateList = null;
  8     public static HolidayHelper Instance
  9     {
 10         get
 11         {
 12             lock (_syncObj)
 13             {
 14                 _instance = new HolidayHelper();
 15             }
 16             return _instance;
 17         }
 18     }
 19     #endregion
 20 
 21     #region 私有方法
 22     /// 
 23     /// 读取文件
 24     /// 
 25     /// 
 26     /// 
 27     private string GetFileContent(string filePath)
 28     {
 29         string result = "";
 30         if (File.Exists(filePath))
 31         {
 32             result = File.ReadAllText(filePath);
 33         }
 34         return result;
 35     }
 36     /// 
 37     /// 获取配置的Json文件
 38     /// 
 39     /// 经过反序列化之后的对象集合
 40     private List GetConfigList()
 41     {
 42         if (cacheDateList == null)
 43         {
 44             string path = string.Format("{0}/../../Config/holidayConfig.json", System.AppDomain.CurrentDomain.BaseDirectory);
 45             string fileContent = GetFileContent(path);
 46             if (!string.IsNullOrWhiteSpace(fileContent))
 47             {
 48                 cacheDateList = Newtonsoft.Json.JsonConvert.DeserializeObject>(fileContent);
 49             }
 50         }
 51         return cacheDateList;
 52     }
 53     /// 
 54     /// 获取指定年份的数据
 55     /// 
 56     /// 
 57     /// 
 58     private DateModel GetConfigDataByYear(int year)
 59     {
 60         List dataSource = GetConfigList();
 61         DateModel result = dataSource.FirstOrDefault(m => m.Year == year);
 62         return result;
 63     }
 64     /// 
 65     /// 判断是否为工作日
 66     /// 
 67     /// 要判断的时间
 68     /// 当前的数据
 69     /// 
 70     private bool IsWorkDay(DateTime currDate, DateModel thisYearData)
 71     {
 72         if (currDate.Year != thisYearData.Year)//跨年重新读取数据
 73         {
 74             thisYearData = GetConfigDataByYear(currDate.Year);
 75         }
 76         if (thisYearData != null)
 77         {
 78             string date = currDate.ToString("MMdd");
 79             int week = (int)currDate.DayOfWeek;
 80 
 81             if (thisYearData.Work.IndexOf(date) >= 0)
 82             {
 83                 return true;
 84             }
 85 
 86             if (thisYearData.Holiday.IndexOf(date) >= 0)
 87             {
 88                 return false;
 89             }
 90 
 91             if (week != 0 && week != 6)
 92             {
 93                 return true;
 94             }
 95         }
 96         return false;
 97     }
 98 
 99     #endregion
100 
101     #region 公共方法
102     public void CleraCacheData()
103     {
104         if (cacheDateList != null)
105         {
106             cacheDateList.Clear();
107         }
108     }
109     /// 
110     /// 根据传入的工作日天数,获得计算后的日期,可传负数
111     /// 
112     /// 天数
113     /// 当天是否算工作日(默认:true)
114     /// 
115     public DateTime GetReckonDate(int day, bool isContainToday = true)
116     {
117         DateTime currDate = DateTime.Now;
118         int addDay = day >= 0 ? 1 : -1;
119 
120         if (isContainToday)
121             currDate = currDate.AddDays(-addDay);
122 
123         DateModel thisYearData = GetConfigDataByYear(currDate.Year);
124         if (thisYearData != null)
125         {
126             int sumDay = Math.Abs(day);
127             int workDayNum = 0;
128             while (workDayNum  sumDay)
129             {
130                 currDate = currDate.AddDays(addDay);
131                 if (IsWorkDay(currDate, thisYearData))
132                     workDayNum++;
133             }
134         }
135         return currDate;
136     }
137 
138     /// 
139     /// 根据传入的时间,计算工作日天数
140     /// 
141     /// 带计算的时间
142     /// 当天是否算工作日(默认:true)
143     /// 
144     public int GetWorkDayNum(DateTime date, bool isContainToday = true)
145     {
146         var currDate = DateTime.Now;
147 
148         int workDayNum = 0;
149         int addDay = date.Date > currDate.Date ? 1 : -1;
150 
151         if (isContainToday)
152         {
153             currDate = currDate.AddDays(-addDay);
154         }
155 
156         DateModel thisYearData = GetConfigDataByYear(currDate.Year);
157         if (thisYearData != null)
158         {
159             bool isEnd = false;
160             do
161             {
162                 currDate = currDate.AddDays(addDay);
163                 if (IsWorkDay(currDate, thisYearData))
164                     workDayNum += addDay;
165                 isEnd = addDay > 0 ? (date.Date > currDate.Date) : (date.Date  currDate.Date);
166             } while (isEnd);
167         }
168         return workDayNum;
169     }
170     #endregion
171 }
172 
173 public class DateModel
174 {
175     public int Year { get; set; }
176 
177     public Liststring> Work { get; set; }
178 
179     public Liststring> Holiday { get; set; }
180 }
View Code

 

  说明下,法定节假日我是自己用json来配置的,大家可以自己维护,或者做成自己的接口。下面展示下json的格式,这是我自己配置的(2015-2017年),大家可以按照自己的需求来修改。

 

技术分享技术分享
 1 [
 2   {
 3     "Year": "2015",
 4     "Work": [ "0104", "0215", "0228", "0906", "1010" ],
 5     "Holiday": [ "0101", "0102", "0103", "0218", "0219", "0220", "0221", "0222", "0223", "0224", "0404", "0405", "0406", "0501", "0502", "0503", "0620", "0621", "0622", "0903", "0904", "0905", "0927", "1001", "1002", "1003", "1004", "1005", "1006", "1007" ]
 6   },
 7   {
 8     "Year": "2016",
 9     "Work": [ "0206", "0214", "0612", "0918", "1008", "1009" ],
10     "Holiday": [ "0101", "0207", "0208", "0209", "0210", "0211", "0212", "0213", "0404", "0501", "0502", "0609", "0610", "0611", "0915", "0916", "0917", "1001", "1002", "1003", "1004", "1005", "1006", "1007" ]
11   },
12   {
13     "Year": "2017",
14     "Work": [ "0122", "0204", "0401", "0527", "0930" ],
15     "Holiday": [ "0101", "0102", "0127", "0128", "0129", "0130", "0201", "0202", "0501", "0529", "0530", "1001", "1002", "1003", "1004", "1005", "1006" ]
16   }
17 ]
holidayConfig.json

  好了,就说这么多,由于能力有限,有写得不好的地方,欢迎指正、补充。如果对您有帮助,请帮忙点个赞,谢谢!

 

C#实现工作日的计算

标签:公司   abs   source   对象   json   没有   默认   param   why   

原文地址:http://www.cnblogs.com/yuan-chong/p/HolidayHelper.html


评论


亲,登录后才可以留言!