首页 > 解决方案 > 如何在两个日期之间的特定时间之间保持计数

问题描述

我正在尝试跟踪您可以从 DateTimePickers 输入的两个日期中一个人吃了多少顿饭。

在以下特定时间之间,每天有三餐:

如果一个人在某个特定时间之后到达,他们就会错过一顿饭,例如,如果我在 2018 年 1 月 1 日凌晨 3 点到达并在 2018 年 1 月 2 日下午 2 点离开,我将只收到 5 顿饭,因为我错过了最后一次一顿饭。

这是我想出的代码,但不幸的是,如果两个日期之间的时间相隔超过一天,我很难弄清楚代码。

    private void button1_Click(object sender, EventArgs e)
    {
        dateTimeExit.CustomFormat = "MM/dd/yyyy hh:mm:ss tt";
        dateTimeArrive.CustomFormat = "MM/dd/yyyy hh:mm:ss tt";
        DateTime timeArrived = dateTimeArrive.Value;
        DateTime timeExit = dateTimeExit.Value;

        int totalHoursArrived = timeArrived.Hour;
        int totalHoursExit = timeExit.Hour;
        int totalCounts = 0;
        int countA = 0; //6-8 AM
        int countB = 0; //12-2PM
        int countC = 0; //5-7PM
        int totalDaysLeft = (timeExit - timeArrived).Days; //determines the number of days between the two given dates.

        if (totalDaysLeft == 1)
        {
            totalCounts = 3;
            countA = 1;
            countB = 1;
            countC = 1;
        }
        else if (totalDaysLeft < 1) //difference between the two dates is less than a day.
        {
            totalCounts = totalDaysLeft * 3;
            countA = totalDaysLeft;
            countB = totalDaysLeft;
            countC = totalDaysLeft;

            if (timeExit.Day == timeArrived.Day) //if the dates are on the same day and "less than one day"
            {
                if (totalHoursArrived <= 8 && totalHoursExit >= 17) //if date is before or on 8AM and leaves on or after 5PM.
                {
                    countA = 1;
                    countB = 1;
                    countC = 1;
                }
                else if (totalHoursArrived <= 8 && (totalHoursExit >= 12 && totalHoursExit < 17)) //if date is before or on 8AM and leaves before 5PM
                {
                    countA = 1;
                    countB = 1;
                }
                else if (totalHoursArrived <= 8 && totalHoursExit < 12) //if date is before or on 8AM and leaves before 12PM
                {
                    countA = 1;
                }
                else if ((totalHoursArrived <= 12 && totalHoursArrived > 8) && totalHoursExit >= 17) //if date is before or on 12PM and leaves on or after 5PM
                {
                    countB = 1;
                    countC = 1;
                }
                else if ((totalHoursArrived <= 12 && totalHoursArrived > 8) && totalHoursExit < 17) //if date is before or on 12PM and leaves before 5PM
                {
                    countB = 1;
                }
                else if (totalHoursArrived >= 17) //if date is after or on 5PM
                {
                    countC = 1;
                }
                totalCounts = countA + countB + countC;
            }
            else //less than a day, but not on same day exit time.
            {
                if (totalHoursArrived <= 8) //if date is before or on 8AM.
                {
                    totalCounts = 3;
                    countA = 1;
                    countB = 1;
                    countC = 1;
                }
                else if (totalHoursArrived >= 12 && totalHoursArrived < 17)// //if date is after or on 12PM and arrival time is less than 5PM
                {
                    totalCounts = 2;
                    countB = 1;
                    countC = 1;
                }
                else if (totalHoursArrived >= 17) //if date is after or on 5PM
                {
                    totalCounts = 1;
                    countC = 1;
                }
                if (totalHoursExit > 0) // exit time
                {
                    if (totalHoursExit >= 17)
                    {
                        totalCounts += 3;
                        countA += 1;
                        countB += 1;
                        countC += 1;
                    }
                    else if (totalHoursExit >= 12 && totalHoursExit < 17)
                    {
                        totalCounts += 2;
                        countA += 1;
                        countB += 1;
                    }
                    else if (totalHoursExit >= 6 && totalHoursExit < 12)
                    {
                        totalCounts += 1;
                        countA += 1;
                    }
                }
            }

        }
        else //more than two days difference between the two dates.
        {
            **//the part I am struggling to figure out**
        }

        lblTotalCountA.Text = "Count A: " + countA;
        lblTotalCountB.Text = "Count B: " + countB;
        lblTotalCountC.Text = "Count C: " + countC;
        lblTotalAmount.Text = "Total Counts: " + totalCounts;
    }

标签: c#datetime

解决方案


我发现您的代码很难维护(如果您想在将来添加第四顿饭,更改代码将是一场噩梦),所以我给您提供不同的方法,并回答您的问题。

首先我会定义一个这样的类:

public class DayMeals
{
   private int[] entryTimes = new int[] { 6, 12, 17 };
   private int[] exitTimes = new int[] { 8, 14, 19 };
   private int[] mealCounts = new int[3];
   private bool countHalfMeals = false;

   public DayMeals(bool countHalfMeals)
   {
       this.countHalfMeals = countHalfMeals;
   }

   public void AddFullDay()
   {
       mealCounts[0]++;
       mealCounts[1]++;
       mealCounts[2]++;
   }

   public void CountMealsForADay(DateTime timeArrived, DateTime timeExit)
   {
       for (int i = 0; i < mealCounts.Length; i++)
       {
           int mealEntryTime = entryTimes[i];
           int mealExitTime = exitTimes[i];
           if (timeArrived.Hour <= mealEntryTime && timeExit.Hour >= mealExitTime)
               mealCounts[i]++;
           else if (countHalfMeals && timeExit.Hour > mealEntryTime && timeExit.Hour <= mealExitTime)
               mealCounts[i]++;
       }
   }

   public void PrintMealsCount()
   {
       for (int i = 0; i < mealCounts.Length; i++)
       {
           System.Console.WriteLine($"Meal #{i + 1} count = {mealCounts[i]}");
       }
   }
}

然后,我将简单地实例化该类并调用函数:

void Main(string[] args)
{
   CalculateMeals(new DateTime(2019, 1, 1, 15, 12, 1), new DateTime(2019, 1, 2, 18, 0, 0));
}

public static void CalculateMeals(DateTime timeArrived, DateTime timeExit)
{
   // Number of full days
   int fullDaysNumber = (timeExit - timeArrived).Days;
   DayMeals dayMeals = new DayMeals(true);
   for (int i = 0; i <= fullDaysNumber; i++)
   {
       int hoursDiff = (int)(timeExit - timeArrived).TotalHours;
       if (timeExit.Day > timeArrived.Day && hoursDiff > 24)
       {
           dayMeals.AddFullDay();
           // A trick to make the cycle work the next time
           // You can use a different variable if you want to keep timeArrived unchanged
           timeArrived = timeArrived.AddDays(1);
       }
       else if (timeExit.Day < timeArrived.Day)
       {
           break;
       }
       else
       {
           if (timeArrived.Day != timeExit.Day)
           {
               dayMeals.CountMealsForADay(timeArrived, new DateTime(1,1,timeArrived.Day,23,59,59));
               dayMeals.CountMealsForADay(new DateTime(1,1,timeExit.Day,0,0,1), timeExit);
           }
           else
           {
               dayMeals.CountMealsForADay(timeArrived, timeExit);
           }    
       }
   }

   dayMeals.PrintMealsCount();
}

我尝试了这段代码,它似乎按预期工作。请查看它并让我知道这是否是您想要实现的目标。

注意:我知道“AddDays(1)”的使用是违反直觉的,因为我将第一天的同一小时保留在接下来的一天。但是,如果您对某个人在周一而不是周二在 11 点进入这一事实不感兴趣,那么用餐数量是相同的。基本上,我只是将入场时间转换为最后一天。


推荐阅读