带有不和谐机器人的C#时间减法

时间:2020-04-24 20:09:06

标签: c# datetime time subtraction discord.net

我正在制作一个有趣的不和谐机器人,该机器人在时钟上找到下一个4:20,无论是上午还是下午,并告诉您直到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 个答案:

答案 0 :(得分:1)

您的代码存在的问题是它无法处理所有可能发生的情况(共有三种):

  • 时间在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有意义。依此类推。

将代码分成两个函数也有许多优点:

  • 您可以独立于漫游器来测试时间计算
  • 代码更加清晰,您没有将通信代码与计算代码混淆。

希望这会有所帮助。

答案 1 :(得分:0)

有一个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.";
            }

答案 2 :(得分:0)

您格式化时间输出似乎还可以,只是为了获得更好的格式,请参见Custom TimeSpan format strings.

您的代码有三个问题:

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.
    ...
}
  1. 正如亚当建议的那样,您必须从.TimeOfDay中删除currentTime,但这还不够。

  2. 您必须处理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.'"));

    }
}