C#实现工作日的计算_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > C#实现工作日的计算

C#实现工作日的计算

 2017/11/5 17:21:39  bug初长成  程序员俱乐部  我要评论(0)
  • 摘要:早就萌生了写博客的想法,一直到现在才动手,原因有多方面,归根结底就是一个字~懒。今天无意看到一片博文,觉得里面说得几点原因很对,原文地址:我们为什么应该坚持写博客,感谢作者,让我有动力写了这篇博文。其实写博文是想记录自己遇到的一些问题的解决思路,方便以后查阅,同时希望可以跟大家一起交流提高。先介绍下本人的基本情况,本人今年刚毕业,坐标上海,.NET菜鸟一枚,第一次写博客,有意见欢迎大家提出,大神轻喷!好了,废话不多说,开门见山。一、开发背景:最近在公司开发的系统中,需要计算工作日
  • 标签:C# 工作 实现

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

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

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

 

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

  

一、开发背景:

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

二、定义:

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

三、实践:

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

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

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

    

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

    

  具体代码:

class="code_img_closed" src="/Upload/Images/2017110517/0015B68B3C38AA5B.gif" alt="">
  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<DateModel> 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     /// <summary>
 23     /// 读取文件
 24     /// </summary>
 25     /// <param name="filePath"></param>
 26     /// <returns></returns>
 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     /// <summary>
 37     /// 获取配置的Json文件
 38     /// </summary>
 39     /// <returns>经过反序列化之后的对象集合</returns>
 40     private List<DateModel> 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<List<DateModel>>(fileContent);
 49             }
 50         }
 51         return cacheDateList;
 52     }
 53     /// <summary>
 54     /// 获取指定年份的数据
 55     /// </summary>
 56     /// <param name="year"></param>
 57     /// <returns></returns>
 58     private DateModel GetConfigDataByYear(int year)
 59     {
 60         List<DateModel> dataSource = GetConfigList();
 61         DateModel result = dataSource.FirstOrDefault(m => m.Year == year);
 62         return result;
 63     }
 64     /// <summary>
 65     /// 判断是否为工作日
 66     /// </summary>
 67     /// <param name="currDate">要判断的时间</param>
 68     /// <param name="thisYearData">当前的数据</param>
 69     /// <returns></returns>
 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     /// <summary>
110     /// 根据传入的工作日天数,获得计算后的日期,可传负数
111     /// </summary>
112     /// <param name="day">天数</param>
113     /// <param name="isContainToday">当天是否算工作日(默认:true)</param>
114     /// <returns></returns>
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     /// <summary>
139     /// 根据传入的时间,计算工作日天数
140     /// </summary>
141     /// <param name="date">带计算的时间</param>
142     /// <param name="isContainToday">当天是否算工作日(默认:true)</param>
143     /// <returns></returns>
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 List<string> Work { get; set; }
178 
179     public List<string> Holiday { get; set; }
180 }
logs_code_collapse">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

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

 

发表评论
用户名: 匿名