C# Вычитание времени с ботом Discord - PullRequest
3 голосов
/ 24 апреля 2020

Я создаю забавного диссон-бота, который находит следующие 4:20 по часам, будь то AM или PM, и говорит вам, как долго до 4:20. Мой код работает отлично до часа до 4:20, а затем пропускает вперед и сообщает, как долго до следующих 4:20 вместо того, чтобы показывать «0 часов 59 минут». Я думаю, что может быть проблема с тем, как я форматирую вывод времени, но я очень плохо знаком с C# и как не знаю, как это исправить. Я включил свой код, а также снимок экрана текущего вывода. На скриншоте у бота тоже минутка, но с тех пор я понял, как это исправить. Я знаю, что код не самый эффективный или чистый, но, опять же, я очень плохо знаком с программированием.

screenshot of bot output

//Finds next 4:20 on the clock
[Command("420")]
public async Task WeedMinute()
{
    DateTime currentTime = DateTime.Now; //Current time
    DateTime weedMinuteMorning = Convert.ToDateTime("4:21:00"); //4:20am
    DateTime weedMinuteEvening = Convert.ToDateTime("16:21:00"); //4:20pm

    string weedMinutePM = "16:21:00"; //These variables are used in subtraction
    string weedMinuteAM = "4:21:00";


    if (currentTime <= weedMinuteEvening)
    {
        //chooseMorningEvening is the output time string
        DateTime chooseMorningEvening = (DateTime.Parse(weedMinutePM).Subtract(currentTime.TimeOfDay));

        await Context.Channel.SendMessageAsync("The next weed minute will happen in " + chooseMorningEvening.ToString(@"hh") + " hours " + chooseMorningEvening.ToString(@"mm") + " minutes.");
    }
    else if (currentTime >= weedMinuteMorning)
    {
        //chooseMorningEvening is the output time string
        DateTime chooseMorningEvening = (DateTime.Parse(weedMinuteAM).Subtract(currentTime.TimeOfDay));

        await Context.Channel.SendMessageAsync("The next weed minute will happen in " + chooseMorningEvening.ToString(@"hh") + " hours " + chooseMorningEvening.ToString(@"mm") + " minutes.");
    }
}

Ответы [ 3 ]

1 голос
/ 25 апреля 2020

Проблема с вашим кодом заключается в том, что он не обрабатывает все случаи, которые могут возникнуть (их три):

  • время между 00:00:00 и 04:20:00 = > рассчитать время до 04: 20: 00
  • время между 04:20:00 и 16:20:00 => рассчитать время до 16: 20: 00
  • время после 16: 20:00 => рассчитать время до 04:20:00 следующего дня.

Вы можете немного упростить эту задачу, если заметите, что время до следующей раздачи всегда должно быть от 0 до 12 часов. , Итак, если вы просто потратите время до 16:20, если оно больше 12 часов, то вы должны быть до 04:20 и вычесть 12 часов. Если время меньше 0 (то есть отрицательно), то вы должны быть позже 16:20, поэтому вы просто добавляете 12 часов. В коде это выглядит так:

    public static TimeSpan CalculateTimeToWeed(DateTime from)
    {
        DateTime weedTime = Convert.ToDateTime("16:20:00");
        TimeSpan twelveHours = TimeSpan.FromHours(12.0);

        TimeSpan timeToWeed = weedTime - from;
        double totalHours = timeToWeed.TotalHours;
        if (totalHours > 12.0)
        {
            timeToWeed -= twelveHours;
        }
        else if (totalHours < 0.0)
        {
            timeToWeed += twelveHours;
        }
        return timeToWeed;
    }

, и вы интегрируете его в своего бота Discord следующим образом:

    [Command("420")]
    public async Task WeedMinute()
    {
        DateTime currentTime = DateTime.Now; 
        TimeSpan timeToWeed = CalculateTimeToWeed(currentTime);
        string message = "The next weed minute will happen in " + timeToWeed.ToString("hh' hours 'mm'  minutes.'");
        await Context.Channel.SendMessageAsync(message);
    }

Вы можете сократить количество строк в этом, но имея эти временные переменные упрощают отладку. Вы можете проверить во время работы с отладчиком, что currentTime - это то, что вы ожидаете, а timeToWeed имеет смысл и т. Д.

Разделение кода на две функции также имеет ряд преимуществ:

  • Вы можете проверить расчет времени независимо от бота
  • Код намного понятнее, вы не путаете код связи с кодом расчета.

Надеюсь, это поможет .

0 голосов
/ 25 апреля 2020

Ваше форматирование вывода времени выглядит нормально, просто для лучших форматов см. Строки пользовательского формата TimeSpan.

Ваш код имеет три проблемы: 1. Если условия

if (currentTime <= weedMinuteEvening)
{
    //this condition is true from 00:00:00 to 16:21:01 so for dates less than 4:21:00
    //you get incorrect output, and next condition execute just for dates greater than 16:21:00.
    ...
}
else if (currentTime >= weedMinuteMorning)
{
   //This code execute only for dates greater than 16:21:00.
    ...
}

Как предложил Адам, вы должны удалить .TimeOfDay из currentTime, но этого недостаточно.

Вы должны обрабатывать даты более 16: 21: 00

Так что я надеюсь, что этот код подойдет вам:

[Command("420")]
public async Task WeedMinute()
{
    DateTime currentTime = DateTime.Now; //Current time
    DateTime weedMinuteMorning = Convert.ToDateTime("4:21:00"); //4:20am
    DateTime weedMinuteEvening = Convert.ToDateTime("16:21:00"); //4:20pm

    //I removed These variables, Don't need to parse same DateTime again. change it as you wish
    //string weedMinutePM = "16:21:00";
    //string weedMinuteAM = "4:21:00";

    if (currentTime <= weedMinuteMorning)
    {
        TimeSpan timeSpan = weedMinuteMorning.Subtract(currentTime);

        await Context.Channel.SendMessageAsync("The next weed minute will happen in " + timeSpan.ToString("hh' hours 'mm'  minutes.'"));
    }
    else if (currentTime <= weedMinuteEvening)
    {
        TimeSpan timeSpan = weedMinuteEvening.Subtract(currentTime);

        await Context.Channel.SendMessageAsync("The next weed minute will happen in " + timeSpan.ToString("hh' hours 'mm'  minutes.'"));
    }
    else
    {
        //To handle dates greater than 16:21:00, we must calculate hours
        //remaining until 4:20 next day.
        weedMinuteMorning = weedMinuteMorning.AddDays(1);
        TimeSpan timeSpan = weedMinuteMorning.Subtract(currentTime);

        await Context.Channel.SendMessageAsync("The next weed minute will happen in " + timeSpan.ToString("hh' hours 'mm'  minutes.'"));

    }
}
0 голосов
/ 25 апреля 2020

Есть функция DateTime.Compare, которую можно использовать здесь, чтобы исправить ошибку, как показано ниже

            //DateTime currentTime = DateTime.Now; //Current time
            DateTime currentTime = Convert.ToDateTime("3:22:00");  // An example time for 0 hours and 59 mins
            DateTime weedMinuteMorning = Convert.ToDateTime("4:21:00"); //4:20am
            DateTime weedMinuteEvening = Convert.ToDateTime("16:21:00"); //4:20pm

            string weedMinutePM = "16:21:00"; //These variables are used in subtraction
            string weedMinuteAM = "4:21:00";

            if(currentTime.CompareTo(weedMinuteMorning) < 1)  //less than or same as Morning 4:20 am
            {
                var chooseMorningEvening = weedMinuteMorning - currentTime;
                string m = "The next weed minute will happen in " + chooseMorningEvening.Hours + " hours " + chooseMorningEvening.Minutes + " minutes.";
            }
            else
            {
                var chooseMorningEvening = weedMinuteEvening - currentTime;
                string m = "The next weed minute will happen in " + chooseMorningEvening.Hours + " hours " + chooseMorningEvening.Minutes + " minutes.";
            }
...