brainpain
brainpain

Reputation: 23

C# Time calculator converting string seconds, to minutes, to hours, to days WITHOUT time span

I am a student extremely confused on this program prompt in which I need to create a program that has an input for the seconds, and when the calculation button is pushed the seconds are displayed along with it's conversion into minutes, hours, and days.

I know my formatting is incorrect, and I've read through my text trying to find something that remotely relates to my program but I am struggling hard to find it.

Can someone explain to me where I'm going wrong and why ?

Again, I'd like to stress that I am still learning C# and haven't gotten to time span yet. So this needs to be in a string conversion as well as in some sort of if-statement.

Please provide an explanation as well because I am wanting to get the hang of this. I also need to have input validation with this, and I've attempted below here.

Here is my code:

private void CalculateButton_Click(object sender, EventArgs e)
    {
        int totalSeconds, minutes, hours, days;
        int secondsInDay = 60 * 60 * 24;
        int secondsInHour = 60 * 60;
        int secondsInMinute = 60;



        if (int.TryParse(secondsInputTextBox.Text, out totalSeconds))

        {
            if (totalSeconds > secondsInDay)
            {
                days = totalSeconds / secondsInDay;
                totalSeconds = totalSeconds - (days * secondsInDay);
                daysTextBox.Text = days.ToString();
            }

            if (totalSeconds > secondsInHour)
            {
                hours = totalSeconds / secondsInHour;
                totalSeconds = totalSeconds - (hours * secondsInHour);
                hoursTextBox.Text = hours.ToString();
            }

            if (totalSeconds > secondsInMinute)
            {
                minutes = totalSeconds / secondsInMinute;
                totalSeconds = totalSeconds - (minutes * secondsInMinute);
                minutesTextBox.Text = minutes.ToString();
            }

            else
            {
                secondsTextBox.Text = totalSeconds.ToString();
            }
        }

        else
        {
            MessageBox.Show("Incorrect input. Please use a number.");
        }

Upvotes: 1

Views: 863

Answers (2)

Steve
Steve

Reputation: 960

I would suggest breaking this procedure into distinct areas - that which performs the arithmetic of conversion, and that which assigns values in the UI.

To break a total_seconds value into days, hours, minutes, and seconds, you'd usually use the (a) integer division and (b) remainder (%) operations.

(Illustrative code example...)

//Calculate values
days = total_seconds / NUM_SECONDS_IN_DAY;
days_rem = total_seconds % NUM_SECONDS_IN_DAY;

hours = days_rem / NUM_SECONDS_IN_HOUR;
hours_rem = days_rem % NUM_SECONDS_IN_HOUR;

minutes = hours_rem / NUM_SECONDS_IN_MINUTE;
minutes_rem = hours_rem % NUM_SECONDS_IN_MINUTE;

seconds = minutes_rem;

//Set textboxes to actual values
daysTextBox.Text = days.ToString();
hoursTextBox.Text = hours.ToString();
minutesTextBox.Text = minutes.ToString();
secondsTextBox.Text = seconds.ToString();

//Blank zero values
if (days < 1) 
{
    daysTextBox.Text = null;
    if (hours < 1) 
    {
        hoursTextBox.Text = null;
        if (minutes < 1) minutesTextBox.Text = null;
    }
}

I wasn't quite clear about the blanking behaviour but I assume I've captured what you needed in blanking quantities down to the level of the smallest non-zero quantity, and leaving seconds in all cases.

Upvotes: 0

RTF
RTF

Reputation: 421

Comments:

  1. The "else if" logic is incorrect. Think about what happens if you have more than an hours worth of seconds: then obviously you have more than a minutes worth of seconds, but your "else if" statement mean this hours block
            else if(hours >= totalSeconds)
                 hours = int.hoursTextBox.Text;

...will never execute.

  1. Your assignment looks backwards. Surely you want to update the corresponding textbox with the computed value.

             int.minutesTextBox.Text = minutes;
  1. However this syntax is also incorrect.
             int.minutesTextBox.Text

"int" is a class and there is no member of int called "minutesTextBox." You want something more like

             minutesTextBox.Text = minutes.ToString();
  1. Less important, but you don't need to TryParse(totalSeconds) if you've already parsed above.

The following is, with slight modifications, a solution.

UPDATE

To get a working solution going, create a WPF application in Visual Studio. In MainWindow.xaml put the following code between your grid tags:

        <Button Width="100" Height="50" Click="CalculateButton_Click" Margin="53,44,564,226"/>      
        <TextBox Name="inputTextBox"  Height="50" Width="100" Margin="298,44,319,226"/>
        <TextBox Name="secondsTextBox"  Height="50" Width="100" Margin="574,233,43,37"/>
        <TextBox Name="minutesTextBox"  Height="50" Width="100" Margin="392,233,225,37"/>
        <TextBox Name="hoursTextBox"  Height="50" Width="100" Margin="198,233,419,37"/>
        <TextBox Name="daysTextBox"  Height="50" Width="100" Margin="53,233,564,37"/>

In MainWindow.xaml.cs add the method:

 private void CalculateButton_Click(object sender, RoutedEventArgs e)
        {

            daysTextBox.Text = null;
            hoursTextBox.Text = null;

            int totalSeconds, minutes, hours, days;
            int secondsInDay = 60 * 60 * 24;
            int secondsInHour = 60 * 60;
            int secondsInMinute = 60;

            int.TryParse(inputTextBox.Text, out totalSeconds);            

            if (totalSeconds > (secondsInDay))
            {
                days = totalSeconds / (secondsInDay);
                totalSeconds = totalSeconds - (days * secondsInDay);
                daysTextBox.Text = days.ToString();
            }
            else daysTextBox.Text = null;

            if (totalSeconds > (secondsInHour))
            {
                hours = totalSeconds / (secondsInHour);
                totalSeconds = totalSeconds - (hours * secondsInHour);
                hoursTextBox.Text = hours.ToString();
            }
            else hoursTextBox.Text = null;

            if (totalSeconds > secondsInMinute)
            {
                minutes = totalSeconds / secondsInMinute;
                totalSeconds = totalSeconds - (minutes * secondsInMinute);
                minutesTextBox.Text = minutes.ToString();
            }
            else minutesTextBox.Text = null;

            if (totalSeconds > 0)
                secondsTextBox.Text = totalSeconds.ToString();
            else secondsTextBox.Text = null;        
        }

This solution is not perfect. A useful exercise would be to add in validation, add in labels and clean up the xaml in general, or translate it into a Windows Forms application. I've added else statements back in, but each else statement is tied to its above if statement. This is logically distinct from else if.

Upvotes: 1

Related Questions