0

I have a program that suggests the time of day to leave to go hunting duck/goose hunting on time. It asks the users for the time of sunrise, how long the drive will take, etc and calculates what time you should leave to make it there on time. My program works but I need to format the results. Example: Sunrise of 7, drive of 30, setup of 30, walking of 30, waiting of 30 results as 4.5 (which is correct) but I want it to read as 4:30. Any Suggestions?? Please and thanks!

Console.WriteLine("Enter sunrise");//7AM would be 420minutes
double sunrise = Convert.ToInt32(Console.ReadLine());
double minutes = sunrise * 60;

double legal = 30;//allowed to shoot 30min before sunrise

Console.WriteLine("How many minutes will it take to drive to" + 
"your destination: ");
double drive = Convert.ToInt32(Console.ReadLine());

Console.WriteLine("How many minutes will it take to set up: ");
double setup = Convert.ToInt32(Console.ReadLine());

Console.WriteLine("How many minutes will it take to walk from " + 
"your vehicle to the actual hunting spot:");
double walking = Convert.ToInt32(Console.ReadLine());

Console.WriteLine("Amount of time between setting up and " + 
"pulling the trigger:");
double waiting = Convert.ToInt32(Console.ReadLine());

double departure = ((minutes - (legal + drive + setup + walking 
+ waiting))/60);//6.5
Console.WriteLine("If sunrise is at " + sunrise +"AM, and it 
takes " + drive + " minutes to drive there you should leave at" + 
departure + "AM");
Duncan
  • 73
  • 1
  • 8
  • 2
    You'll probably want to use the TimeSpan.FromMinutes() method to create a TimeSpan, then pass [a format string](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-timespan-format-strings) to the ToString() method off of that TimeSpan. – StriplingWarrior Jan 09 '18 at 23:06
  • `double drive = Convert.ToInt32` why are you converting to int when you want a double? – Camilo Terevinto Jan 09 '18 at 23:06
  • 2
    You might take a look at [How do I represent a time only value in .NET?](https://stackoverflow.com/questions/2037283/how-do-i-represent-a-time-only-value-in-net) and use TimeSpan rather than some hacked together integer math. – C-Pound Guru Jan 09 '18 at 23:07

6 Answers6

1

Change your

double ... = Convert.ToInt32(Console.ReadLine());

To

TimeSpan ... = TimeSpan.FromMinutes(int.Parse(Console.ReadLine()); 

And then use:

TimeSpan departure = sunrise - (legal + drive + setup + waiting);

Console.WriteLine("If sunrise is at {0}AM, and it takes {1} minutes to drive there you should leave at {2}AM", 
     sunrise, drive.Minutes, departure);

You can then play with TimeSpan formatting until you get the desired output.

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
  • But as NetMage said, if you have to deal with the timer overlowing AM, you propably have to use a full DateTime. It might even deal with TImezones and DST. Time formating, storing and measurement are not easy at all: https://www.youtube.com/watch?v=-5wpm-gesOY – Christopher Jan 09 '18 at 23:17
  • @Christopher The OP is just learning, I don't see any mention of willing to store the output. You shouldn't over complicate a simple problem – Camilo Terevinto Jan 09 '18 at 23:18
  • Time is **never** a simple problem. It never was and it never will be. The only thing that is better at frustrating programmers is langauge. It is one of those things programmers are best of learning as early as possible :) – Christopher Jan 09 '18 at 23:21
  • @Christopher, OP doesn't included the handle of dates, although Time zones are important in any language, for this simple question it will be over complicating. – Orel Eraki Jan 09 '18 at 23:38
  • I still think it is better to forewarn him taht this stuff **will** get messy quickly, so he does not think that would be a good set of beginners examples. Half the world does not use AM/PM in the first place. And I would bet you there is some country where the switch is on a differen hour. – Christopher Jan 09 '18 at 23:40
0
DateTime.Today.AddHours(departure).ToLongTimeString()
LeY
  • 659
  • 7
  • 21
  • 2
    you must be very busy, we understand.Please take some time to add some description. – Muhammad Omer Aslam Jan 10 '18 at 01:05
  • 1
    While this code may answer the question, providing additional context regarding **how** and **why** it solves the problem would improve the answer's long-term value. – Alexander Jan 10 '18 at 03:55
0

One way to do it would be to get the sunrise time as a Time format (hh:mm) from the user, and the other values as minutes. Then you can convert sunrise to a DateTime, subtract 30 minutes, and subtract the total of the rest of the times. This will leave you with a DateTime result, which is easy to format with AM/PM information.

To assist in getting valid input from the user, I would create the following two methods, which get a TimeSpan and an int from the user (along with necessary retries if they input incorrect data). Note that the one that gets a TimeSpan only expects the hours and minutes, and automatically adds :00 for the seconds:

private static TimeSpan GetTimeFromUser(string prompt)
{
    Console.Write(prompt);
    TimeSpan result;

    while (!TimeSpan.TryParse(Console.ReadLine() + ":00", out result))
    {
        Console.WriteLine("Please use format hh:mm for the time.");
        Console.Write(prompt);
    }

    return result;
}

private static int GetIntFromUser(string prompt)
{
    Console.Write(prompt);
    int result;

    while (!int.TryParse(Console.ReadLine(), out result))
    {
        Console.WriteLine("Please enter a valid integer.");
        Console.Write(prompt);
    }

    return result;
}

With those helper functions out of the way, we can get the info from the user pretty easily, and then display back the results:

private static void Main()
{
    DateTime sunrise = DateTime.Today.Add(GetTimeFromUser("Enter sunrise time: "));
    DateTime legalStartTime = sunrise.AddMinutes(-30);

    int driveTime = GetIntFromUser(
        "How many minutes will it take to drive to your destination: ");
    int setupTime = GetIntFromUser(
        "How many minutes will it take to set up: ");
    int walkTime = GetIntFromUser(
        "How many minutes will it take to walk from your vehicle to the hunting spot: ");
    int waitTime = GetIntFromUser(
        "Number of minutes between setting up and pulling the trigger: ");
    int totalTime = driveTime + setupTime + walkTime + waitTime;

    DateTime departureTime = legalStartTime.AddMinutes(-totalTime);

    Console.WriteLine($"If sunrise is at {sunrise:hh:mm tt}, and it takes {totalTime} " +
        $"minutes to drive and get ready, you should leave at: {departureTime:hh:mm tt}");

    Console.WriteLine("\nDone!\nPress any key to exit...");
    Console.ReadKey();
}

Output

enter image description here

Rufus L
  • 36,127
  • 5
  • 30
  • 43
0

Although few solutions were introduced, i felt the need to add more complete but naive solution, which will handle sunrise as DateTime and represent result as time.

Console.WriteLine("Sunrise at:");
var sunrise = DateTime.Parse(Console.ReadLine());

Console.WriteLine("How many minutes will it take to drive to your destination: ");
var drive = TimeSpan.FromMinutes(int.Parse(Console.ReadLine()));

Console.WriteLine("How many minutes will it take to set up: ");
var setup = TimeSpan.FromMinutes(int.Parse(Console.ReadLine()));

Console.WriteLine("How many minutes will it take to walk from your vehicle to the actual hunting spot:");
var walking = TimeSpan.FromMinutes(int.Parse(Console.ReadLine()));

Console.WriteLine("Amount of time between setting up and pulling the trigger:");
var waiting = TimeSpan.FromMinutes(int.Parse(Console.ReadLine()));

var legalTimeBeforeSunriseInMin = TimeSpan.FromMinutes(30);
var calculatedDelta = (legalTimeBeforeSunriseInMin + drive + setup + walking + waiting);
var departure = sunrise.Add(-calculatedDelta).ToLongTimeString();
Console.WriteLine($"If sunrise is at {sunrise.ToLongTimeString()}, and it takes {drive} minutes to drive there you should leave at {departure}");
Orel Eraki
  • 11,940
  • 3
  • 28
  • 36
0
double t = 4.5;
TimeSpan s = TimeSpan.FromMinutes(t * 60);
string result = s.ToString(@"h\:mm");
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
-1

If you have a time in fractional hours like

var departTimeInHours = 4.5;

And you want to display it as a 12-hour time formatted string with colon and AM/PM, one possibility is to create a DateTime from the fractional hours and use that type's built-in string conversion, which has the advantage of being localized (are there non AM/PM localized time formats?). The simplest way to convert the fractional hours to a DateTime is to convert them to ticks (which are 100 nanosecond units) and then call the constructor.

var strDepartTime = (new DateTime((long)(departTimeInHours*60*60*10000000)).ToString("t");
NetMage
  • 26,163
  • 3
  • 34
  • 55
  • Creating a `DateTime` when you care only about time to end up formatting it as time? Not really the best option – Camilo Terevinto Jan 09 '18 at 23:09
  • Rebuilding the wheel isn't a great idea either. This will properly handle AM/PM automatically. – NetMage Jan 09 '18 at 23:12
  • @CamiloTerevinto Don't forget premature optimization is the root of all evil. Though a better constructor could be used. – NetMage Jan 09 '18 at 23:33
  • While this code may answer the question, providing additional context regarding **how** and **why** it solves the problem would improve the answer's long-term value. – Alexander Jan 10 '18 at 03:34
  • This problem seems either too simple for SO, or too obvious to me, to require explanation but I added some exposition. – NetMage Jan 10 '18 at 17:17