`

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)

运行结果


  • 大小: 114.1 KB
分享到:
评论

相关推荐

    C#定时间段执行(注意是时间段|例:12:40-15:20分内执行)(原作)

    上次自己想找个定时间段执行提示的小程序,但找了好久没有找到,就自己想方法做了个定时间段执行的小程序。还行吧!(自己想了好久才做出来的) 定时间段执行(注意是时间段|例:12:40-15:20分内执行) 希望有更好的 ...

    C# WinFrom 根据时间段和时刻间隔产生随机日期

    C# WinForm 对日期函数是操作,在日期与字符串指间的转换处理可以做个例子看看吧。 程序的主要功能是,输入yyyy-MM-dd 的两个时间间隔和输入HH格式的时刻间隔,则随机产出在两个范围内的指定书目的随机数。

    C#按指定时间段查询数据

    摘要:C#源码,数据库应用,SQL查询实例 查询指定时间段的数据库数据,基于visual C#源码实现,检索数据库中符合特定时间段内的所有记录,这是一个经常被用到的实用技巧,按时间查询不管是在C#,或是在VB/VC等程序开发...

    C# 输入开始、结束时间,自动计算工时数(区分工作日和非工作日)

    本主题聚焦于一个特定的C#应用:输入开始和结束时间后,自动计算工时数,同时考虑了工作日与非工作日(包括节假日)的区别以及不同时间段的工时倍数。 首先,我们需要理解C#中的DateTime类,它是处理日期和时间的...

    C#基础教程C# C# C# C#

    【C#基础教程C# C# C# C#】是一份专门为C#编程语言初学者设计的详尽教程。C#(读作“C Sharp”)是微软公司于2000年推出的一种面向对象的、类型安全的、现代的编程语言,主要用于构建Windows平台的应用程序、Web应用...

    C#圆形按钮,非常漂亮动态

    "C#圆形按钮,非常漂亮动态"这个标题描述了一个特殊的按钮控件,它不仅具有圆形的外观,而且可能还包含一些动态效果,使得交互体验更加生动。这种设计可以增加应用程序的视觉吸引力,并提升用户体验。 C#是微软开发...

    C# Timer对象来倒计时一个设定的时间并循环播放一段音乐

    在这个场景中,我们使用`Timer`来实现一个倒计时功能,并在倒计时过程中循环播放一段音乐。这个应用可能适用于游戏、定时提醒或者任何需要定时触发事件的软件。 首先,让我们了解一下C#中的`System.Timers.Timer`类...

    C# Winform ListView添加按钮列

    在C#编程中,Winform应用常常需要展示数据并提供交互功能。`ListView`控件是Windows Forms中常用的一种控件,它能够以列表形式显示数据,并支持多种视图模式,如图标、列表、详细信息等。然而,标准的`ListView`控件...

    C#做的3D按钮,有多种效果

    1. Windows Forms或WPF:C#的GUI开发通常基于这两个框架之一。Windows Forms是.NET Framework的传统UI库,而WPF(Windows Presentation Foundation)是.NET Core和.NET 5及更高版本的新一代UI框架,提供更强大的3D...

    c# winform 非常漂亮的按钮 玻璃按钮效果 按钮样式 风格 希望可以给大家提供帮助 源码

    在C# WinForm开发中,我们经常会遇到需要创建独特、美观的用户界面,而自定义按钮的样式和效果就是其中重要的一环。本资源提供的"非常漂亮的按钮 - 玻璃按钮效果"就是一个很好的示例,它展示了如何利用C#语言和...

    WinForm圆形按钮(C#)

    本话题将深入探讨如何利用C#语言制作一个圆形按钮,这个按钮不仅具有基本的点击事件处理能力,还可以通过调整参数实现音乐播放器中常见的样式。下面我们将详细介绍这个自定义控件的实现过程、设计思路以及相关的知识...

    C#圆形按钮,非常漂亮动态~~

    在.NET框架中,C#是一种常用的编程语言,用于开发各种应用程序。在GUI(图形用户界面)设计时,按钮是不可或缺的元素。标题“C#圆形按钮,非常漂亮动态~~”暗示我们将讨论如何在C#中创建一个具有独特视觉效果的圆形...

    C#中以时间作为chart的X坐标轴间隔

    在C#编程中,创建一个以时间为X轴坐标的图表是一项常见的需求,特别是在数据分析和可视化领域。本篇文章将深入探讨如何在C#中实现这一功能,以时间作为chart的X坐标轴间隔,尤其是在波形图的场景下。 首先,我们...

    C#圆角按钮

    在C#编程中,圆角按钮是一种常见的UI元素,它为用户界面增添了一种现代感和视觉吸引力。本文将深入探讨如何在C#中实现圆角按钮,通过提供的描述和标题,我们可以推断这是一个关于创建自定义控件的示例代码。我们将...

    c#使用maskedTextBox控件制作的IP地址输入,按“.”可以跳到下一段

    本教程将详细介绍如何利用maskedTextBox控件来创建一个允许用户按照IPv4格式(即四段式,每段数字范围0-255,段间用“.”分隔)输入IP地址的界面,并实现按“.”键自动跳转到下一段的功能。 首先,我们需要在...

    c# 示例 点击按钮打开图片

    2. **Button 控件**: 在这个示例中,我们有一个Button控件,它是用户与程序交互的主要方式之一。当用户点击按钮时,会触发一个事件,我们可以为这个事件编写代码来响应用户的操作。 3. **PictureBox 控件**: ...

    C#自定义控件:一个简单的圆形按钮源码

    在.NET Framework中,C#是一种常用的编程语言,用于开发Windows应用程序。Visual Studio 2010(VS2010)是微软提供的一个强大的集成开发环境(IDE),它支持C#编程并提供丰富的工具和功能。在本示例中,我们将深入...

    NTP时间同步客户端程序C#源码

    总之,NTP时间同步客户端程序C#源码提供了一个很好的学习和实践平台,对于提升C#网络编程和时间同步技术的理解大有裨益。你可以通过分析和修改源码,加深对NTP协议和C#网络编程的理解,进而开发出适应自己需求的时间...

    C# NTP 时钟同步 获取指定IP系统时间

    在C#中,我们可以创建一个SNTP客户端来与远程NTP服务器通信,获取其时间戳,然后将该时间应用到本地系统。以下是一个简单的SNTP客户端示例: ```csharp using System.Net; using System.Net.NetworkInformation; ...

    一个 C# 做的日记本

    【标题】"一个 C# 做的日记本"揭示了这个项目是使用C#编程语言开发的一个应用程序,主要用于创建和管理个人日记。C#是一种面向对象的、现代的编程语言,由微软公司开发,广泛应用于Windows平台上的软件开发,包括...

Global site tag (gtag.js) - Google Analytics