【问题标题】:C# Time Subtraction With a Discord Bot使用 Discord 机器人进行 C# 时间减法
【发布时间】:2020-08-08 12:21:12
【问题描述】:

我正在制作一个有趣的 Discord 机器人,它可以在时钟上找到下一个 4:20,无论是上午还是下午,并告诉你距离 4:20 还有多长时间。我的代码在 4:20 前一个小时之前运行良好,然后它会向前跳并告诉下一个 4:20 需要多长时间,而不是显示“0 小时 59 分钟”。我在想我如何格式化时间输出可能存在问题,但我对 C# 很陌生,也不知道如何解决它。我已经包含了我的代码以及当前输出的屏幕截图。在屏幕截图中,机器人也有一分钟的时间,但从那时起我就想出了如何解决这个问题。我知道代码不是最高效或最干净的,但我还是对编程很陌生。

//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.");
    }
}

【问题讨论】:

  • 我认为从 currentTime 中删除 TimeOfDay 就足够了

标签: c# datetime time subtraction discord.net


【解决方案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 是否合理等等。

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

  • 您可以独立于机器人测试时间计算
  • 代码更清晰,没有把通信代码和计算代码混为一谈。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您的时间输出格式似乎没问题,只是为了获得更好的格式,请参阅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. 按照 Adam 的建议,您必须从 currentTime 中删除 .TimeOfDay,但这还不够。

    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.'"));
    
        }
    }
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2019-05-10
        • 2018-06-26
        • 1970-01-01
        • 2020-08-18
        • 2018-06-12
        • 2021-04-19
        • 2021-05-11
        • 2020-02-14
        • 2021-02-19
        相关资源
        最近更新 更多