c# 划份时间段之一 (按自然月)
最近做项目中,发现这两个方法非常不错,记下来。以备后用
测试
运行结果
/// <summary> /// //////按自然月计算应收日期 /// </summary> public partial class WYTableFunction { public enum enumPeroiod { NotSplit=0,//不分隔,起始与截止整个是一周期。 First=1,//只取第一期 AllPeroid=2//取所有周期。 } //如果有应收日,那就以合同的应收日为准,否刚就为应收日期就为自然月最后一天 /// <summary> /// 计算应收日期及所属期 /// CybleBeginDate:周期实际的起始日 /// CybleEndDate:周期实际的结束日。 /// </summary> /// <param name="UnitType">周期单位</param> /// <param name="Cycle">周期</param> /// <param name="sBeginDate">起始日期</param> /// <param name="sEndDate">截止日期</param> /// <param name="ExesType">应收类别,1代表提前,2代表本期,3代表延后</param> /// <param name="ExesMonth">指定月份,0代表本期</param> /// <param name="AccDate">指定应收天数,0代表每期最后一天</param> /// <returns></returns> [SqlFunction(TableDefinition = @" BeginDate DateTime,EndDate DateTime,GatheringDate DateTime,CybleBeginDate DateTime,CycleEndDate DateTime", FillRowMethodName = "FillRow2")] public static IEnumerable CW_F_CalDateTable_CLR(int UnitType, int Cycle, string sBeginDate, string sEndDate, int ExesType, int ExesMonth, int AccDate, int iEnumPeroiod,bool ReturnDataRow) { enumPeroiod Peroid = (enumPeroiod)iEnumPeroiod; DateTime BeginDate = Convert.ToDateTime(sBeginDate); DateTime EndDate = Convert.ToDateTime(sEndDate); DateTime AccountDate = DateTime.MinValue; List<DateTime[]> rowList = new List<DateTime[]>(); DateTime dtBegin = BeginDate, dtEnd = DateTime.MinValue; DateTime dtCybleBeginDate = new DateTime(dtBegin.Year, dtBegin.Month, 1), dtCycleEndDate = EndDate; //Globe.SendString(string.Format("生成周期,从{0}至{1}",BeginDate,EndDate)); switch (UnitType) { #region 年交 case 1://年 while (dtBegin <= EndDate) { if (Peroid == enumPeroiod.NotSplit) { dtEnd = EndDate; } else { /*2011-6-14,首期,是算到当前期间的最后一天,之后才是加一个周期*/ if (dtEnd == DateTime.MinValue) dtEnd = new DateTime(dtBegin.Year, 12, 31).AddYears(Cycle - 1);//按自然月,则首期,加上周期减1(有可能是每2年或每3年) else dtEnd = new DateTime(dtEnd.Year, 12, 31).AddYears(Cycle); } dtCycleEndDate = dtEnd; dtCybleBeginDate = dtEnd.AddDays(1).AddYears(-Cycle);//例:2011-12-31,变2012-1-1,再减1年(设Cycle为1) if (dtEnd > EndDate) dtEnd = EndDate; AccountDate = CalAccountDate(dtBegin, dtEnd, ExesType, ExesMonth, AccDate); rowList.Add(new DateTime[] { dtBegin, dtEnd, AccountDate,dtCybleBeginDate, dtCycleEndDate }); if (Peroid!=enumPeroiod.AllPeroid) break; dtBegin = dtEnd.AddDays(1); } break; #endregion #region 季交 case 2://季 while (dtBegin <= EndDate) { if (Peroid == enumPeroiod.NotSplit) { dtEnd = EndDate; } else { if (dtEnd == DateTime.MinValue) dtEnd = new DateTime(dtBegin.Year, dtBegin.Month, 1).AddMonths((Cycle - 1) * 3); else dtEnd = new DateTime(dtEnd.Year, dtEnd.Month, 1).AddMonths(Cycle * 3); switch (dtEnd.Month) { case 1: case 2: case 3: dtEnd = new DateTime(dtEnd.Year, 3, 31); break; case 4: case 5: case 6: dtEnd = new DateTime(dtEnd.Year, 6, 30); break; case 7: case 8: case 9: dtEnd = new DateTime(dtEnd.Year, 9, 30); break; case 10: case 11: case 12: dtEnd = new DateTime(dtEnd.Year, 12, 31); break; } } dtCycleEndDate = dtEnd; dtCybleBeginDate = dtEnd.AddDays(1).AddMonths(-(Cycle * 3));//倒退到起始日。例:结束日期是2011-3-31,则先变为2011-4-1,再减一季(3个月),则变为2011-1-1 if (dtEnd > EndDate) dtEnd = EndDate; AccountDate = CalAccountDate(dtBegin, dtEnd, ExesType, ExesMonth, AccDate); rowList.Add(new DateTime[] { dtBegin, dtEnd, AccountDate, dtCybleBeginDate, dtCycleEndDate }); if (Peroid != enumPeroiod.AllPeroid) break; dtBegin = dtEnd.AddDays(1); } break; #endregion #region 月交 case 3://月 while (dtBegin <= EndDate) { if (Peroid == enumPeroiod.NotSplit) { dtEnd = EndDate; } else { if (dtEnd == DateTime.MinValue) dtEnd = new DateTime(dtBegin.Year, dtBegin.Month, 1).AddMonths(Cycle).AddDays(-1);//本 else dtEnd = new DateTime(dtEnd.Year, dtEnd.Month, 1).AddMonths(Cycle + 1).AddDays(-1);//注意:这个dtEnd,每次都是上一周期所在月的最后一天,所以取当月,加上周期Cycle加1,得到后月(设Cycle=1)第1天,再减1天。 } dtCycleEndDate = dtEnd; dtCybleBeginDate = new DateTime(dtCycleEndDate.Year, dtCycleEndDate.Month, 1); if (dtEnd > EndDate) dtEnd = EndDate; //Globe.SendString(string.Format("计算自然月时:起始{0:yyyy-MM-dd},结束{1:yyyy-MM-dd},周期:{2}", dtBegin,dtEnd,Cycle)); AccountDate = CalAccountDate(dtBegin, dtEnd, ExesType, ExesMonth, AccDate); //Globe.SendString(string.Format("计算应收日:ExesType={0},ExesMonth={1},AccDate={2},AccountDate={3:yyyy-MM-dd}", ExesType, ExesMonth, AccDate, AccountDate)); rowList.Add(new DateTime[] { dtBegin, dtEnd, AccountDate, dtCybleBeginDate, dtCycleEndDate }); if (Peroid != enumPeroiod.AllPeroid) break; dtBegin = dtEnd.AddDays(1); } break; #endregion #region 周交 case 4://周 while (dtBegin <= EndDate) { /*2011-6-15,这里有些问题没有按星期来计周。以后再改,ljh*/ if (Peroid == enumPeroiod.NotSplit) { dtEnd = EndDate; } else { dtEnd = dtBegin.AddDays(Cycle * 7); } dtCycleEndDate = dtEnd.AddDays(-1); dtCybleBeginDate = dtCycleEndDate.AddDays(-7 * Cycle); if (dtEnd > EndDate) dtEnd = EndDate; else dtEnd = dtEnd.AddDays(-1); AccountDate = CalAccountDate(dtBegin, dtEnd, ExesType, ExesMonth, AccDate); rowList.Add(new DateTime[] { dtBegin, dtEnd, AccountDate, dtCybleBeginDate, dtCycleEndDate }); if (Peroid != enumPeroiod.AllPeroid) break; dtBegin = dtEnd.AddDays(1); } break; #endregion #region 日交 case 5://日 while (dtBegin <= EndDate) { dtEnd = dtBegin.AddDays(Cycle); if (dtEnd > EndDate) dtEnd = EndDate; else dtEnd = dtEnd.AddDays(-1); dtCycleEndDate = dtBegin; dtCybleBeginDate = dtBegin; AccountDate = CalAccountDate(dtBegin, dtEnd, ExesType, ExesMonth, AccDate); rowList.Add(new DateTime[] { dtBegin, dtEnd, AccountDate, dtCybleBeginDate, dtCycleEndDate }); if (Peroid != enumPeroiod.AllPeroid) break; dtBegin = dtEnd.AddDays(1); } break; #endregion #region 其他 case 6: { dtEnd = EndDate; dtCycleEndDate = dtEnd; dtCybleBeginDate = dtBegin; AccountDate = CalAccountDate(dtBegin, dtEnd, ExesType, ExesMonth, AccDate); rowList.Add(new DateTime[] { BeginDate, EndDate, AccountDate, dtCybleBeginDate, dtCycleEndDate }); if (Peroid != enumPeroiod.AllPeroid) break; } break; #endregion } DataTable dt=new DataTable(); dt.Columns.Add("BeginDate",typeof(DateTime)); dt.Columns.Add("EndDate",typeof(DateTime)); dt.Columns.Add("GatheringDate",typeof(DateTime)); dt.Columns.Add("CycleBeginDate", typeof(DateTime)); dt.Columns.Add("CycleEndDate", typeof(DateTime)); for (int i = 0; i < rowList.Count; i++) { DataRow row = dt.NewRow(); row["BeginDate"] = rowList[i][0]; row["EndDate"] = rowList[i][1]; row["GatheringDate"] = rowList[i][2]; row["CycleBeginDate"] = rowList[i][3]; row["CycleEndDate"] = rowList[i][4]; dt.Rows.Add(row); } if (ReturnDataRow==true) return dt.Rows as IEnumerable; else return rowList as IEnumerable; //返回一个string 数组,这个数组符合IEnumerable接口,当然你也可以返回hashtable等类型。 //return (IEnumerable)dt.Rows.GetEnumerator(); } private static DateTime CalAccountDate(DateTime dtBegin,DateTime dtEnd, int DelayType,int DelayMonth, int DelayDay) { DateTime dtAccount = dtEnd; //Globe.SendString(string.Format("\r\n************{0},{1},{2}", DelayType, DelayMonth, DelayDay)); switch (DelayType) { case 1://提前提前N个月 dtAccount = new DateTime(dtBegin.Year, dtBegin.Month, 1); dtAccount = dtAccount.AddMonths(-DelayMonth); break; case 3://延后 dtAccount = new DateTime(dtEnd.Year, dtEnd.Month, 1); dtAccount = dtAccount.AddMonths(DelayMonth); break; case 4://指定月份 if (DelayMonth<1 || DelayMonth>12) dtAccount = new DateTime(dtEnd.Year, dtEnd.Month, 1); else dtAccount = new DateTime(dtEnd.Year, DelayMonth, 1); break; case 2://本期 default: dtAccount = new DateTime(dtEnd.Year, dtEnd.Month, 1); break; } DateTime dtMonthLast=new DateTime(dtAccount.Year, dtAccount.Month, 1).AddMonths(1).AddDays(-1); int MonthDays = dtMonthLast.Day;//应收所在月份的天数。 if (DelayDay <= 0 || DelayDay > MonthDays) dtAccount = dtMonthLast; else dtAccount = new DateTime(dtAccount.Year, dtAccount.Month, DelayDay); return dtAccount; } }
测试
select * from CW_F_CalDateTable_CLR(3,1,'2013-01-15','2014-01-14',3,1,15,2,0)
运行结果
相关推荐
上次自己想找个定时间段执行提示的小程序,但找了好久没有找到,就自己想方法做了个定时间段执行的小程序。还行吧!(自己想了好久才做出来的) 定时间段执行(注意是时间段|例:12:40-15:20分内执行) 希望有更好的 ...
C# WinForm 对日期函数是操作,在日期与字符串指间的转换处理可以做个例子看看吧。 程序的主要功能是,输入yyyy-MM-dd 的两个时间间隔和输入HH格式的时刻间隔,则随机产出在两个范围内的指定书目的随机数。
摘要:C#源码,数据库应用,SQL查询实例 查询指定时间段的数据库数据,基于visual C#源码实现,检索数据库中符合特定时间段内的所有记录,这是一个经常被用到的实用技巧,按时间查询不管是在C#,或是在VB/VC等程序开发...
本主题聚焦于一个特定的C#应用:输入开始和结束时间后,自动计算工时数,同时考虑了工作日与非工作日(包括节假日)的区别以及不同时间段的工时倍数。 首先,我们需要理解C#中的DateTime类,它是处理日期和时间的...
【C#基础教程C# C# C# C#】是一份专门为C#编程语言初学者设计的详尽教程。C#(读作“C Sharp”)是微软公司于2000年推出的一种面向对象的、类型安全的、现代的编程语言,主要用于构建Windows平台的应用程序、Web应用...
"C#圆形按钮,非常漂亮动态"这个标题描述了一个特殊的按钮控件,它不仅具有圆形的外观,而且可能还包含一些动态效果,使得交互体验更加生动。这种设计可以增加应用程序的视觉吸引力,并提升用户体验。 C#是微软开发...
在这个场景中,我们使用`Timer`来实现一个倒计时功能,并在倒计时过程中循环播放一段音乐。这个应用可能适用于游戏、定时提醒或者任何需要定时触发事件的软件。 首先,让我们了解一下C#中的`System.Timers.Timer`类...
在C#编程中,Winform应用常常需要展示数据并提供交互功能。`ListView`控件是Windows Forms中常用的一种控件,它能够以列表形式显示数据,并支持多种视图模式,如图标、列表、详细信息等。然而,标准的`ListView`控件...
1. Windows Forms或WPF:C#的GUI开发通常基于这两个框架之一。Windows Forms是.NET Framework的传统UI库,而WPF(Windows Presentation Foundation)是.NET Core和.NET 5及更高版本的新一代UI框架,提供更强大的3D...
在C# WinForm开发中,我们经常会遇到需要创建独特、美观的用户界面,而自定义按钮的样式和效果就是其中重要的一环。本资源提供的"非常漂亮的按钮 - 玻璃按钮效果"就是一个很好的示例,它展示了如何利用C#语言和...
本话题将深入探讨如何利用C#语言制作一个圆形按钮,这个按钮不仅具有基本的点击事件处理能力,还可以通过调整参数实现音乐播放器中常见的样式。下面我们将详细介绍这个自定义控件的实现过程、设计思路以及相关的知识...
在.NET框架中,C#是一种常用的编程语言,用于开发各种应用程序。在GUI(图形用户界面)设计时,按钮是不可或缺的元素。标题“C#圆形按钮,非常漂亮动态~~”暗示我们将讨论如何在C#中创建一个具有独特视觉效果的圆形...
在C#编程中,创建一个以时间为X轴坐标的图表是一项常见的需求,特别是在数据分析和可视化领域。本篇文章将深入探讨如何在C#中实现这一功能,以时间作为chart的X坐标轴间隔,尤其是在波形图的场景下。 首先,我们...
在C#编程中,圆角按钮是一种常见的UI元素,它为用户界面增添了一种现代感和视觉吸引力。本文将深入探讨如何在C#中实现圆角按钮,通过提供的描述和标题,我们可以推断这是一个关于创建自定义控件的示例代码。我们将...
本教程将详细介绍如何利用maskedTextBox控件来创建一个允许用户按照IPv4格式(即四段式,每段数字范围0-255,段间用“.”分隔)输入IP地址的界面,并实现按“.”键自动跳转到下一段的功能。 首先,我们需要在...
2. **Button 控件**: 在这个示例中,我们有一个Button控件,它是用户与程序交互的主要方式之一。当用户点击按钮时,会触发一个事件,我们可以为这个事件编写代码来响应用户的操作。 3. **PictureBox 控件**: ...
在.NET Framework中,C#是一种常用的编程语言,用于开发Windows应用程序。Visual Studio 2010(VS2010)是微软提供的一个强大的集成开发环境(IDE),它支持C#编程并提供丰富的工具和功能。在本示例中,我们将深入...
总之,NTP时间同步客户端程序C#源码提供了一个很好的学习和实践平台,对于提升C#网络编程和时间同步技术的理解大有裨益。你可以通过分析和修改源码,加深对NTP协议和C#网络编程的理解,进而开发出适应自己需求的时间...
在C#中,我们可以创建一个SNTP客户端来与远程NTP服务器通信,获取其时间戳,然后将该时间应用到本地系统。以下是一个简单的SNTP客户端示例: ```csharp using System.Net; using System.Net.NetworkInformation; ...
【标题】"一个 C# 做的日记本"揭示了这个项目是使用C#编程语言开发的一个应用程序,主要用于创建和管理个人日记。C#是一种面向对象的、现代的编程语言,由微软公司开发,广泛应用于Windows平台上的软件开发,包括...