如何计算C#中两个日期之间的天数减去星期日?

时间:2009-07-07 17:09:17

标签: c#

我正在创建一个图书馆管理系统。

我已经使用时间戳来计算日期差异,并且在日期差异的帮助下我也在计算罚款。

现在这个日期差异包括一周内的所有日子。但是对于图书馆的申请,罚款只需要在周内收取6天(周一至周六)。

我无法做到这一点。

任何人都可以帮我完成这项任务吗?

提前致谢!!

6 个答案:

答案 0 :(得分:17)

基本上,您可以计算原始天数;你需要找到从这个数字中减去的星期日数。您知道每7天是一个星期日,因此您可以将原始天数除以7,并从原始天数中减去该数字。现在你需要删除存在的周剩余时间的星期日数量;原始天数的 mod 会告诉您剩余的天数。要确定该跨度是否包含星期日,您必须知道第一天的星期几;如果你定义星期一是0,星期二是1,星期三是3等,那么如果你把跨度开始的星期几的值加到原始数的mod(7)天数,如果数字是6或更高,你已经延长了一个星期日,并且应该从你的罚款号码中删除1天。

在伪代码中:

int fine;
int numdays =  endDay - startDay;

fine = numdays - (numdays / 7);

int dayOfWeek = startDate.DayOfWeek;
if (dayOfWeek + (numdays % 7) > 6)
{
   fine = fine - 1;
}

答案 1 :(得分:8)

这样做:

private int DaysLate(DateTime dueDate, DateTime returnDate)
{
    var ts = returnDate - dueDate;
    int dayCount = 0;

    for (int i = 1; i <= ts.Days; i++)
    {
        if (dueDate.AddDays(i).DayOfWeek != DayOfWeek.Sunday)
            dayCount++;
    }

    return dayCount;
}

答案 2 :(得分:2)

基于Jacob Proffitt答案,但没有内存列表的开销。由于DaysBetween动态生成日期,因此在生成列表时计算计数:

int c = DaysBetween(begin, end).Count(d => d.DayOfWeek != DayOfWeek.Sunday);

private IEnumerable<DateTime> DaysBetween(DateTime begin, DateTime end)
{
    for(var d = begin; d <= end; d.AddDays(1)) yield return d;
}

当然,如果你不想炫耀LINQ,你可以简化它并使用一个函数:

private int DaysBetween(DateTime begin, DateTime end)
{
    int count = 0;
    for(var d = begin; d <= end; d.AddDays(1)) 
       if(d.DayOfWeek != DayOfWeek.Sunday) count++
    return count;
}

恕我直言,这些都比每个人的最爱(乌鸦的答案)更清晰,更容易理解,调试,排除故障和修改。

当然,这是一个O(n)解决方案,意味着日子分开的越多,计算所需的时间就越长。虽然对于大多数现实世界的应用程序来说这可能是好的,但在某些情况下,您可能更喜欢基于公式的方法,这些方法也是如此:

int q = end.Subtract(begin).Days - (end.Subtract(begin).Days / 7);

答案 3 :(得分:1)

快速测试并且似乎适用于您的目的:(编辑:添加了一些注释以便清晰和更正代码错误)

private static int CalculateDaysToFine(DateTime dateDue, DateTime dateIn)
        {
            TimeSpan ts = dateIn - dateDue;
            int daysToFine = ts.Days - (ts.Days/7); //subtract full weeks (1 Sunday each)
            if (((int)dateDue.DayOfWeek + (ts.Days%7)) >6) //check to see if the remaining days contain a Sunday
                daysToFine--;
            return daysToFine;
        }

答案 4 :(得分:0)

这是我的实施。我的目标是使用与McWafflestix类似的方法执行O(1)执行时间。我试图保持它的可读性,最大化OO代码并尽可能地减少“数学魔法”(不是说我有任何反对数学的东西......或者魔法)。

这个想法是确定截止日期和返回日期之间完整的7天周的数量,以及通过调整数量的“delta”天数。只要你能保证截止日期和返回日期都不属于星期日(我从你的描述中假设不会出现问题),这将按预期工作。

        static int CalculateFineDays(DateTime due, DateTime returned)
        {
            TimeSpan ts = returned - due;
            if (ts < TimeSpan.Zero)
                return 0;
int delta = returned.DayOfWeek - due.DayOfWeek; return delta + ts.Subtract(TimeSpan.FromDays(delta)).Days * 6 / 7; }

编辑:我之前提出了一个解决方案并发现了一个错误,当我正在研究它时,我将代码缩减到了这个。

答案 5 :(得分:-2)

我的Linqy方法(具有易于阅读的优点,但在创建结构类型列表方面受到轻微的性能影响):

private int DaysLate(DateTime dateDue, DateTime dateReturned)
{
    return getDayList(dateDue, dateReturned).Where(d => d.DayOfWeek != DayOfWeek.Sunday).Count();
}

private List<DateTime> getDayList(DateTime begin, DateTime end)
{
    List<DateTime> dates = new List<DateTime>();
    DateTime counter = begin;
    while (counter <= end)
    {
        dates.Add(counter);
        counter = counter.AddDays(1);
    }
    return dates;
}