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

时间:2022-03-15 19:16:45

I am creating a Library Management System.

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

I have used the timestamp to calculate the Date Difference and with the help of date difference I am calculating the Fine also.

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

Now this date difference includes all days in a week. But for a library application fine should be charged only for 6 days(Mon - Sat) in Week.

现在,此日期差异包括一周中的所有日期。但是对于图书馆应用程序,罚款只需在周内收取6天(周一至周六)。

I am not able to do this.

我无法做到这一点。

Can anyone help me out in performing this task?

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

Thanks in advance!!

提前致谢!!

6 个解决方案

#1


Essentially, you can calculate the raw number of days; you need to find the number of Sundays to be subtracted from that number. You know that every 7 days is a Sunday, so you can divide your raw number of days by 7, and subtract that number from your raw number of days. Now you need to remove the number of Sundays in the remainder of the week that exists; a mod of the raw number of days will tell you the remainder days. To find out if that span includes a Sunday, you must know the day of the week of the first day; if you define Monday to be 0, Tuesday to be 1, Wednesday to be 3, etc., then if you add the value of the day of the week of the beginning of the span to the mod (7) of the raw number of days, if the number is 6 or greater, you have spanned an additional Sunday, and should remove 1 day from your fine number.

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

In pseudocode:

int fine;
int numdays =  endDay - startDay;

fine = numdays - (numdays / 7);

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

#2


This will do it:

这样做:

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;
}

#3


Based on Jacob Proffitt answer but without the overhead of in-memory List. Since the DaysBetween yields its dates dynamically, the count is calculated as the list is generated:

基于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;
}

Of course if you didn't want to showoff LINQ you could simplify it and go with one function:

当然,如果你不想炫耀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;
}

IMHO both of these are cleaner and easier to understand, debug, troubleshoot, and modify than the everybody's favorite (raven's answer).

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

Of course, this is an O(n) solution, meaning the more the days are apart, the longer it takes to calculate. While this may be Ok for most of real world applications, in some cases you may prefer a formula-based approach, something along these lines:

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

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

#4


Tested this quickly and seems to work for your purposes:(edit: added some comments for clarity and corrected code error)

快速测试,似乎适用于您的目的:(编辑:添加一些注释,以清楚和纠正代码错误)

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;
        }

#5


Here is my implementation. My goal was O(1) execution time using a similar approach to McWafflestix. I tried to keep it readable, maximizing OO code and minimizing "math magic" as much as possible (not that I have anything against math... or magic for that matter).

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

The idea is to determine the number of complete 7-day weeks between the due date and returned date, and a "delta" number of days to adjust it by to correct the number. As long as you can guarantee that neither the due date nor the returned date fall on a Sunday (which I presume from your description will not be a problem) this will work as expected.

这个想法是确定截止日期和返回日期之间完整的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; }

Edit: I had posed a solution earlier and found a bug in it, and as I was working on it I reduced the code down to this.

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

#6


My Linqy approach (has the virtue of being easier to read but takes a minor performance hit of creating a List of structure types):

我的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;
}

#1


Essentially, you can calculate the raw number of days; you need to find the number of Sundays to be subtracted from that number. You know that every 7 days is a Sunday, so you can divide your raw number of days by 7, and subtract that number from your raw number of days. Now you need to remove the number of Sundays in the remainder of the week that exists; a mod of the raw number of days will tell you the remainder days. To find out if that span includes a Sunday, you must know the day of the week of the first day; if you define Monday to be 0, Tuesday to be 1, Wednesday to be 3, etc., then if you add the value of the day of the week of the beginning of the span to the mod (7) of the raw number of days, if the number is 6 or greater, you have spanned an additional Sunday, and should remove 1 day from your fine number.

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

In pseudocode:

int fine;
int numdays =  endDay - startDay;

fine = numdays - (numdays / 7);

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

#2


This will do it:

这样做:

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;
}

#3


Based on Jacob Proffitt answer but without the overhead of in-memory List. Since the DaysBetween yields its dates dynamically, the count is calculated as the list is generated:

基于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;
}

Of course if you didn't want to showoff LINQ you could simplify it and go with one function:

当然,如果你不想炫耀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;
}

IMHO both of these are cleaner and easier to understand, debug, troubleshoot, and modify than the everybody's favorite (raven's answer).

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

Of course, this is an O(n) solution, meaning the more the days are apart, the longer it takes to calculate. While this may be Ok for most of real world applications, in some cases you may prefer a formula-based approach, something along these lines:

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

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

#4


Tested this quickly and seems to work for your purposes:(edit: added some comments for clarity and corrected code error)

快速测试,似乎适用于您的目的:(编辑:添加一些注释,以清楚和纠正代码错误)

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;
        }

#5


Here is my implementation. My goal was O(1) execution time using a similar approach to McWafflestix. I tried to keep it readable, maximizing OO code and minimizing "math magic" as much as possible (not that I have anything against math... or magic for that matter).

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

The idea is to determine the number of complete 7-day weeks between the due date and returned date, and a "delta" number of days to adjust it by to correct the number. As long as you can guarantee that neither the due date nor the returned date fall on a Sunday (which I presume from your description will not be a problem) this will work as expected.

这个想法是确定截止日期和返回日期之间完整的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; }

Edit: I had posed a solution earlier and found a bug in it, and as I was working on it I reduced the code down to this.

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

#6


My Linqy approach (has the virtue of being easier to read but takes a minor performance hit of creating a List of structure types):

我的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;
}