独孤求教:两个日期之间的天数,除去周末后,剩余的天数的函数。求优化!

call_from_dream 2016-12-03 12:58:07
小弟刚写了一个函数,是求两个日期之间,除去周末后,剩余天数的。感觉算法上写的不是太好。求大神指点!
PS:一开始是用swich-case 语句实现的,功能实现后,发现return 变量时,报错,说return的local变量未赋值。小弟我只好用if-else语句重写了这个功能。
代码如下:
static int workdaysCalculate(DateTime beginTime, DateTime endTime)
{
byte bt = (byte)(beginTime.DayOfWeek);
byte et = (byte)(endTime.DayOfWeek);
int spanDays = endTime.Subtract(beginTime).Days;
int workDays;

if (6 == bt)
{
if (6 == et)
{
workDays = spanDays * 5 / 7;
}
else if (0 == et)
{
workDays = (spanDays - 1) * 5 / 7;
}
else
{
workDays = (spanDays - et - 1) * 5 / 7 + et - 1;
}
}
else if (0 == bt)
{
if (0 == et)
{
workDays = (spanDays - et) * 5 / 7;
}
else
{
workDays = (spanDays - et) * 5 / 7 + et - 1;
}
}
else if (1 == bt)
{
if (0 == et)
{
workDays = (spanDays - 6) * 5 / 7 + 5;
}
else
{
workDays = (spanDays - et + 1) * 5 / 7 + et - 1;
}
}
else if (2 == bt)
{
if ((0 == et) || (1 == et))
{
workDays = (spanDays - 5 - et) * 5 / 7 + 4;
}
{
workDays = (spanDays - et + 2) * 5 / 7 + et - 2;
}
}
else if (3 == bt)
{
if (0 == et)
{
workDays = (spanDays - 4) * 5 / 7 + 3;
}
else if ((1== et)||(2==et))
{
workDays = (spanDays - et - 4) * 5 / 7 + et + 2;
}else
{
workDays = (spanDays - et + 3) * 5 / 7 + et - 3;
}
}
else if (4 == bt)
{
if (0 == et)
{
workDays = (spanDays - 3) * 5 / 7 + 2;
}
else if ((4 == et) || (5 == et) || (6 == et))
{
workDays = (spanDays - et + 4) * 5 / 7 + et - 4;
}
else
{
workDays = (spanDays - et - 3) * 5 / 7 + et + 1;
}
}
else
{
if (0 == et)
{
workDays = (spanDays - 2) * 5 / 7 + 1;
}
else if ((5 == et) || (6 == et))
{
workDays = (spanDays - et + 5) * 5 / 7 + et - 5;
}
else
{
workDays = (spanDays - et - 2) * 5 / 7 + et;
}
}

/*
switch (bt)
{
//When begin day is Saturday
case 6:
switch (et)
{
case 6:
workDays = spanDays * 5 / 7;
break;
case 0:
workDays = (spanDays - 1) * 5 / 7;
break;
case 1:
case 2:
case 3:
case 4:
case 5:
workDays = (spanDays-et-1) * 5 / 7 + et-1;
break;
}
break;
//When begin day is Sunday.
case 0:
switch (et)
{
case 0:
workDays = (spanDays - et) * 5 / 7;
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
workDays = (spanDays - et) * 5 / 7 + et - 1;
break;
}

break;

case 1:
switch (et)
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
workDays = (spanDays - et + 1) * 5 / 7 + et - 1;
break;
case 0:
workDays = (spanDays-6) * 5 / 7 + 5;
break;
}
break;

case 2:
switch (et)
{
case 2:
case 3:
case 4:
case 5:
case 6:
workDays = (spanDays - et + 2) * 5 / 7 + et - 2;
break;
case 0:
case 1:
workDays = (spanDays - 5 - et) * 5 / 7 + 4;
break;
}
break;

case 3:
switch (et)
{
case 3:
case 4:
case 5:
case 6:
workDays = (spanDays - et + 3) * 5 / 7 + et - 3;
break;
case 0:
workDays = (spanDays - 4) * 5 / 7 + 3;
break;
case 1:
case 2:
workDays = (spanDays - et - 4) * 5 / 7 + et + 2;
break;
}
break;

case 4:
switch (et)
{
case 4:
case 5:
case 6:
workDays = (spanDays - et + 4) * 5 / 7 + et - 4;
break;
case 0:
workDays = (spanDays - 3) * 5 / 7 + 2;
break;
case 1:
case 2:
case 3:
workDays = (spanDays - et - 3) * 5 / 7 + et + 1;
break;
}
break;

case 5:
switch (et)
{
case 5:
case 6:
workDays = (spanDays - et + 5) * 5 / 7 + et - 5;
break;
case 0:
workDays = (spanDays - 2) * 5 / 7 + 1;
break;
case 1:
case 2:
case 3:
case 4:
workDays = (spanDays - et - 2) * 5 / 7 + et;
break;
}
break;
}
*/
return workDays;

}
...全文
633 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
wuweide1 2016-12-05
  • 打赏
  • 举报
回复
谢谢分享!!!
  • 打赏
  • 举报
回复
引用 7 楼 xuzuning 的回复:
        static int workdaysCalculate(DateTime beginTime, DateTime endTime)
        {
            int bt = (int)(beginTime.DayOfWeek);
            int et = (int)(endTime.DayOfWeek);
            int spanDays = endTime.Subtract(beginTime).Days + 1;
            return spanDays - ((spanDays + bt) / 7 * 2) + (et == 6 ? 1 : 0);
        }
正怒月神 2016-12-05
  • 打赏
  • 举报
回复
就这么个小程序, 为何要去纠结性能上的事情。
  • 打赏
  • 举报
回复
引用 10 楼 call_from_dream 的回复:
[quote=引用 3 楼 u011981242 的回复:] 一堆if else, case switch看的头皮发麻啊,用这个方法吧
/// <summary>  
/// 计算两个日期的工作日总数(包括起始日期当天和结束日期当天)  
/// </summary>  
/// <param name="start"></param>  
/// <param name="end"></param>  
/// <returns></returns>  
private static int GetNumberOfWorkDays(DateTime start, DateTime end)  
{  
    int days = 0;  
    while (start <= end)  
    {  
        if (start.DayOfWeek != DayOfWeek.Saturday && start.DayOfWeek != DayOfWeek.Sunday)  
        {  
            ++days;  
        }  
        start = start.AddDays(1);  
    }  
    return days;  
}  
但是如果含有法定节假日不在周六周日的就得另写一个库存储这些日期,并且方法中要将这些日期排出
大哥,你这么判断,如果时间跨度长点,每个时间都判断后再决定,那时间复杂度就高了![/quote]你可以测试下计算从2000年1月1日到2016年12月5日的耗时,最好用差点的电脑测试,看看有多耗时
bigbaldy 2016-12-05
  • 打赏
  • 举报
回复
引用 7 楼 xuzuning 的回复:
        static int workdaysCalculate(DateTime beginTime, DateTime endTime)
        {
            int bt = (int)(beginTime.DayOfWeek);
            int et = (int)(endTime.DayOfWeek);
            int spanDays = endTime.Subtract(beginTime).Days + 1;
            return spanDays - ((spanDays + bt) / 7 * 2) + (et == 6 ? 1 : 0);
        }
这方法好,收藏了
xuzuning 2016-12-05
  • 打赏
  • 举报
回复
spanDays 是总体的天数 bt 是第一天的 星期几 那么 spanDays + bt 就是从第一天所在周的星期天(0)算起的天数 (spanDays + bt) / 7 有多少周 (spanDays + bt) / 7 * 2 每周两个休息日,所以乘 2 et == 6 ? 1 : 0 如果最后一天是周 6,那么就还回一天,前面多减了
  • 打赏
  • 举报
回复
引用 11 楼 call_from_dream 的回复:
[quote=引用 9 楼 sp1234 的回复:] 因为“星期”是有规律的,所以你用不着每一天都去计算一下DayOfWeek,而只要把第一天是周几计算出来,然后顺延去 ++1 就能知道后边的每一天是周几了。
谢谢!不过,我感觉,把时间跨度中的每一天都遍历一遍,这个性能耗费有点高,特别是时间跨度比较长的情况下[/quote] 高多少呢?你给个测试出来!这里其实没有什么是非可论,你如果不拿出符合测试的数字来说其实就不能说明问题。 例如,我认为对于几百天的所谓“跨度”,多耗费2毫秒,根本不算是什么“耗费有点高”。
crystal_lz 2016-12-05
  • 打赏
  • 举报
回复
引用 13 楼 sp1234 的回复:
[quote=引用 11 楼 call_from_dream 的回复:] [quote=引用 9 楼 sp1234 的回复:] 因为“星期”是有规律的,所以你用不着每一天都去计算一下DayOfWeek,而只要把第一天是周几计算出来,然后顺延去 ++1 就能知道后边的每一天是周几了。
谢谢!不过,我感觉,把时间跨度中的每一天都遍历一遍,这个性能耗费有点高,特别是时间跨度比较长的情况下[/quote] 高多少呢?你给个测试出来!这里其实没有什么是非可论,你如果不拿出符合测试的数字来说其实就不能说明问题。 例如,我认为对于几百天的所谓“跨度”,多耗费2毫秒,根本不算是什么“耗费有点高”。[/quote] 我已经测了1992、1、1 到 9993、1、1 一个80毫秒左右运行完毕 如果扯代码优化倒是可以 但是这点循环就扯性能问题 感觉有点懵 那我平时写的上百万级别的循环是不是要把电脑资源沾满啊
  • 打赏
  • 举报
回复
因为“星期”是有规律的,所以你用不着每一天都去计算一下DayOfWeek,而只要把第一天是周几计算出来,然后顺延去 ++1 就能知道后边的每一天是周几了。
  • 打赏
  • 举报
回复
    static int workdaysCalculate(DateTime beginTime, DateTime endTime)
    {
        var days = endTime.Date.Subtract(beginTime.Date).TotalDays;
        int wt = (int)beginTime.DayOfWeek;
        var result = 0;
        for (var i = 0; i < days; ++i, ++wt)
        {
            if (wt == 7)
                wt = 0;
            if (wt > 0 && wt < 6)
                result++;
        }
        return result;
    }
call_from_dream 2016-12-04
  • 打赏
  • 举报
回复
引用 7 楼 xuzuning 的回复:
        static int workdaysCalculate(DateTime beginTime, DateTime endTime)
        {
            int bt = (int)(beginTime.DayOfWeek);
            int et = (int)(endTime.DayOfWeek);
            int spanDays = endTime.Subtract(beginTime).Days + 1;
            return spanDays - ((spanDays + bt) / 7 * 2) + (et == 6 ? 1 : 0);
        }
大哥,您后面写的那个(spanDays + bt) / 7 * 2) 我不太明白意思
call_from_dream 2016-12-04
  • 打赏
  • 举报
回复
引用 9 楼 sp1234 的回复:
因为“星期”是有规律的,所以你用不着每一天都去计算一下DayOfWeek,而只要把第一天是周几计算出来,然后顺延去 ++1 就能知道后边的每一天是周几了。
谢谢!不过,我感觉,把时间跨度中的每一天都遍历一遍,这个性能耗费有点高,特别是时间跨度比较长的情况下
call_from_dream 2016-12-04
  • 打赏
  • 举报
回复
引用 3 楼 u011981242 的回复:
一堆if else, case switch看的头皮发麻啊,用这个方法吧
/// <summary>  
/// 计算两个日期的工作日总数(包括起始日期当天和结束日期当天)  
/// </summary>  
/// <param name="start"></param>  
/// <param name="end"></param>  
/// <returns></returns>  
private static int GetNumberOfWorkDays(DateTime start, DateTime end)  
{  
    int days = 0;  
    while (start <= end)  
    {  
        if (start.DayOfWeek != DayOfWeek.Saturday && start.DayOfWeek != DayOfWeek.Sunday)  
        {  
            ++days;  
        }  
        start = start.AddDays(1);  
    }  
    return days;  
}  
但是如果含有法定节假日不在周六周日的就得另写一个库存储这些日期,并且方法中要将这些日期排出
大哥,你这么判断,如果时间跨度长点,每个时间都判断后再决定,那时间复杂度就高了!
xuzuning 2016-12-04
  • 打赏
  • 举报
回复
        static int workdaysCalculate(DateTime beginTime, DateTime endTime)
        {
            int bt = (int)(beginTime.DayOfWeek);
            int et = (int)(endTime.DayOfWeek);
            int spanDays = endTime.Subtract(beginTime).Days + 1;
            return spanDays - ((spanDays + bt) / 7 * 2) + (et == 6 ? 1 : 0);
        }
_明月 2016-12-04
  • 打赏
  • 举报
回复
引用 5 楼 u011981242 的回复:
[quote=引用 4 楼 dear_Alice_moon 的回复:] [quote=引用 3 楼 u011981242 的回复:] 一堆if else, case switch看的头皮发麻啊,用这个方法吧
/// <summary>  
/// 计算两个日期的工作日总数(包括起始日期当天和结束日期当天)  
/// </summary>  
/// <param name="start"></param>  
/// <param name="end"></param>  
/// <returns></returns>  
private static int GetNumberOfWorkDays(DateTime start, DateTime end)  
{  
    int days = 0;  
    while (start <= end)  
    {  
        if (start.DayOfWeek != DayOfWeek.Saturday && start.DayOfWeek != DayOfWeek.Sunday)  
        {  
            ++days;  
        }  
        start = start.AddDays(1);  
    }  
    return days;  
}  
但是如果含有法定节假日不在周六周日的就得另写一个库存储这些日期,并且方法中要将这些日期排出
问一下,你为何要使用静态函数?不是静态函数会占用内存资源较多,一般使用动态函数的么? 求指点,谢谢。 [/quote]不静态请问如何调用方法?是不是得实例化,实例化和静态的内存消耗你觉得有多大差别?[/quote] 不是在同一个类中可以声明一个动态函数啊,直接调用动态函数啊? 例如:

public void SayHello() 
{
      Console.WriteLine("Hi~~~~,你好啊。");
}
  • 打赏
  • 举报
回复
引用 4 楼 dear_Alice_moon 的回复:
[quote=引用 3 楼 u011981242 的回复:] 一堆if else, case switch看的头皮发麻啊,用这个方法吧
/// <summary>  
/// 计算两个日期的工作日总数(包括起始日期当天和结束日期当天)  
/// </summary>  
/// <param name="start"></param>  
/// <param name="end"></param>  
/// <returns></returns>  
private static int GetNumberOfWorkDays(DateTime start, DateTime end)  
{  
    int days = 0;  
    while (start <= end)  
    {  
        if (start.DayOfWeek != DayOfWeek.Saturday && start.DayOfWeek != DayOfWeek.Sunday)  
        {  
            ++days;  
        }  
        start = start.AddDays(1);  
    }  
    return days;  
}  
但是如果含有法定节假日不在周六周日的就得另写一个库存储这些日期,并且方法中要将这些日期排出
问一下,你为何要使用静态函数?不是静态函数会占用内存资源较多,一般使用动态函数的么? 求指点,谢谢。 [/quote]不静态请问如何调用方法?是不是得实例化,实例化和静态的内存消耗你觉得有多大差别?
_明月 2016-12-03
  • 打赏
  • 举报
回复
引用 3 楼 u011981242 的回复:
一堆if else, case switch看的头皮发麻啊,用这个方法吧
/// <summary>  
/// 计算两个日期的工作日总数(包括起始日期当天和结束日期当天)  
/// </summary>  
/// <param name="start"></param>  
/// <param name="end"></param>  
/// <returns></returns>  
private static int GetNumberOfWorkDays(DateTime start, DateTime end)  
{  
    int days = 0;  
    while (start <= end)  
    {  
        if (start.DayOfWeek != DayOfWeek.Saturday && start.DayOfWeek != DayOfWeek.Sunday)  
        {  
            ++days;  
        }  
        start = start.AddDays(1);  
    }  
    return days;  
}  
但是如果含有法定节假日不在周六周日的就得另写一个库存储这些日期,并且方法中要将这些日期排出
问一下,你为何要使用静态函数?不是静态函数会占用内存资源较多,一般使用动态函数的么? 求指点,谢谢。
assky124 2016-12-03
  • 打赏
  • 举报
回复
其实,存数据库里最好,节假日会有调整
  • 打赏
  • 举报
回复
一堆if else, case switch看的头皮发麻啊,用这个方法吧
/// <summary>  
/// 计算两个日期的工作日总数(包括起始日期当天和结束日期当天)  
/// </summary>  
/// <param name="start"></param>  
/// <param name="end"></param>  
/// <returns></returns>  
private static int GetNumberOfWorkDays(DateTime start, DateTime end)  
{  
    int days = 0;  
    while (start <= end)  
    {  
        if (start.DayOfWeek != DayOfWeek.Saturday && start.DayOfWeek != DayOfWeek.Sunday)  
        {  
            ++days;  
        }  
        start = start.AddDays(1);  
    }  
    return days;  
}  
但是如果含有法定节假日不在周六周日的就得另写一个库存储这些日期,并且方法中要将这些日期排出
真相重于对错 2016-12-03
  • 打赏
  • 举报
回复
大致说一下,可以通过第一个日期的dayofweek,和两个日期间的天数,获取共有几个周末

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧