I'm making a funny discord bot that finds the next 4:20 on the clock, whether it's AM or PM, and tells you how long until 4:20. My code is working perfectly until an hour before 4:20 and then it skips ahead and tells how long until the next 4:20 instead of showing "0 hours 59 minutes". I'm thinking that there may be an issue with how I'm formatting the time output but I'm very new to C# and how no idea how to fix it. I have included my code and also a screenshot of the current output. In the screenshot the bot is also a minute off but I've since then figured out how to fix that. I know the code isn't the most efficient or clean but again, I'm very new to programming.
//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.");
}
}
The problem with your code is that it does not handle all the cases that can occur (there are three):
You can simplify this a little if you observe that the time till your next toke should always be between 0 and 12 hours. So, if you just take the time until 16:20, if it is greater than 12 hours then you must be up before 04:20 and you can subtract 12 hours. If the time is less than 0 (that is, negative) then you must be later than 16:20 so you just add 12 hours. In code this looks like this:
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;
}
and you would integrate it into your Discord bot as follows:
[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);
}
You could cut down the number of lines in this, but having these temporary variable makes thing easier to debug. You can check while stepping through with a debugger that currentTime
is what you expect and timeToWeed
makes sense and so on.
Breaking the code into two functions also has a number of advantages:
Hope this helps.