Как вести учет между определенным временем между двумя датами - PullRequest
0 голосов
/ 06 января 2019

Я пытаюсь отследить, сколько еды человек дал за две даты, которые вы можете ввести из DateTimePickers.

В определенное время между:

есть три приема пищи в день.
  • 6-8 утра Еда 1
  • 12-2PM Питание 2
  • 5-7 вечера еды 3

Если человек прибывает после определенного времени, он пропускает прием пищи, поэтому, например, если я приеду 1 января 2018 года в 3 часа ночи и уеду 2 января 2018 года в 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;
    }

Ответы [ 3 ]

0 голосов
/ 06 января 2019

Вот, пожалуйста, без зацикливания. Я упростил далее, используя только стандартные объекты C #. Хитрость заключается в том, чтобы считать полные дни и работать с таймпансами.

public static void Main(string[] args)
        {
            DateTime timeArrived = new DateTime(2019, 1, 5, 13, 53, 0);
            DateTime timeExit = new DateTime(2019, 1, 6, 8, 46, 0);

            TimeSpan startMeal1 = new TimeSpan(6, 0, 0);
            TimeSpan endMeal1 = new TimeSpan(8, 0, 0);
            TimeSpan startMeal2 = new TimeSpan(12, 0, 0);
            TimeSpan endMeal2 = new TimeSpan(14, 0, 0);
            TimeSpan startMeal3 = new TimeSpan(17, 0, 0);
            TimeSpan endMeal3 = new TimeSpan(19, 0, 0);


            int daysDiff = (timeExit - timeArrived).Days;

            int meals1Count = daysDiff;
            int meals2Count = daysDiff;
            int meals3Count = daysDiff;

            TimeSpan timeDiff = timeExit - timeArrived - TimeSpan.FromDays(daysDiff);

            if (timeArrived.TimeOfDay <= endMeal1 && (timeArrived.TimeOfDay + timeDiff) >= startMeal1) meals1Count++;
            if (timeArrived.TimeOfDay <= endMeal2 && (timeArrived.TimeOfDay + timeDiff) >= startMeal2) meals2Count++;
            if (timeArrived.TimeOfDay <= endMeal3 && (timeArrived.TimeOfDay + timeDiff) >= startMeal3) meals3Count++;
        }
0 голосов
/ 06 января 2019

Я не проверял это в VS, но что-то вроде этого должно работать. Я скопировал ваш код того же дня, предполагая, что он также корректен:

public class MealCalculation
    {
        int countA, countB, countC = 0;
        int total = 0;
        public void Calculate()
        {

            var start = DateTime.Now;
            var finish = DateTime.Now;

            // Same Day
            if (start.Date == finish.Date)
            {
                MealsCalculate(start.Hour, start.Hour);
            }
            // Next Day
            else if (start.AddDays(1).Date == finish.Date)
            {
                MealsCalculate(start.Hour, 24);
                MealsCalculate(0, finish.Hour);
            }
            // Great Than 1 Day
            else
            {
                // First Day
                MealsCalculate(start.Hour, 24);

                // Middle Full Days
                var days = NumberOfDays(start.Date, finish.Date);
                countA += days;
                countB += days;
                countC += days;

                // Finish Day
                MealsCalculate(0, finish.Hour);
            }

            // Total
            total = countA + countB + countC;

        }
        public int NumberOfDays(DateTime start, DateTime finish)
        {
            var days = 0;
            while (start < finish)
            {
                start.AddDays(1);
                days++;
            }
            return days - 1;
        }


        public void MealsCalculate(int totalHoursArrived, int totalHoursExit)
        {
            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;
            }
        }

    }
0 голосов
/ 06 января 2019

Я считаю, что ваш код довольно трудно поддерживать (если вы хотите добавить четвертый прием пищи в будущем, это будет кошмаром для изменения кода), поэтому я даю вам другой подход, а также отвечаю ваш вопрос.

Сначала я бы определил класс следующим образом:

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)» нелогично, потому что я сохраняю тот же час дня 1 для следующего дня. Но если вас не интересует тот факт, что человек вошел в 11 часов в понедельник, а не во вторник, количество приемов пищи остается тем же. По сути, я просто перенес время входа в последний день.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...