Problem: Time Calculation from Number of Seconds in C

Problem

We want to create a function called time_calculation.

This function has a return type of void and takes as input the total number of seconds elapsed since midnight. It must return the corresponding time in terms of corresponding hours, minutes, and seconds.

For example, providing the value 41130 as input, the function must return three values corresponding to:

  • Number of hours: 11;
  • Number of minutes: 25;
  • Number of seconds: 30.

Implementation

Reading the text of this exercise, the first thing we must notice is that the time_calculation function takes one parameter as input, the number of seconds, and returns three values: the number of hours, the number of minutes, and the number of seconds.

For this reason, we must use pointers as function arguments. A possible function signature is the following:

void time_calculation(type number_seconds, type *hours, type *minutes, type *seconds);

Therefore, the number_seconds argument will be passed by copy, while the hours, minutes, and seconds arguments will be passed in the form of pointers.

What remains to be understood is the type of these arguments.

For the number_seconds type, we can use a long int, or simply long, since it represents the number of seconds elapsed but the exercise text does not provide us with an upper limit to its value. This is why we choose a long, making the function robust enough to handle large numbers. Since the number of seconds elapsed cannot be negative, we can use an unsigned long.

As for hours, minutes, and seconds, we can trivially use an unsigned int, or simply unsigned. In fact, hours are between 0 and 23 while minutes and seconds are between 0 and 59.

For this reason, the function signature becomes:

void time_calculation(unsigned long number_seconds,
                    unsigned int *hours,
                    unsigned int *minutes,
                    unsigned int *seconds);

Let's now try to implement the function.

The first operation to perform is to bring back the total number of seconds to a range between 0 and the maximum number of seconds that elapse in a day. In fact, the number of seconds in a day is equal to:

\mbox{seconds} = 24 \cdot 60 \cdot 60 = 86400

If the number_seconds parameter should exceed this value, we must bring it back to the interval [0, 86400]. Therefore:

void time_calculation(unsigned long number_seconds,
                    unsigned int *hours,
                    unsigned int *minutes,
                    unsigned int *seconds) {

    const long number_seconds_in_a_day = 86400;

    /*
     * We bring back the total number of seconds
     * to the interval [0, 86400]
     */
    number_seconds %= number_seconds_in_a_day;

    /* ... */

}

We used the modulo operation. In this way, we discard possibly the number of seconds corresponding to one or more complete days.

Now we must calculate the number of hours. To do this, we just need to divide the total number of seconds by the number of seconds that elapse in an hour. Before doing this, however, it is convenient to store the excess number of seconds through a modulo operation. Therefore:

void time_calculation(unsigned long number_seconds,
                    unsigned int *hours,
                    unsigned int *minutes,
                    unsigned int *seconds) {

    const long number_seconds_in_a_day = 86400;
    const long number_seconds_in_an_hour = 3600;

    /* Support variable */
    unsigned long remaining_seconds = 0;

    /*
     * We bring back the total number of seconds
     * to the interval [0, 86400]
     */
    number_seconds %= number_seconds_in_a_day;

    /*
     * We calculate the number of hours and save the number
     * of excess seconds
     */
    remaining_seconds = number_seconds % number_seconds_in_an_hour;
    *hours = (number_seconds - remaining_seconds) / number_seconds_in_an_hour;

    /* ... */

}

We apply the same reasoning to the calculation of minutes:

void time_calculation(unsigned long number_seconds,
                    unsigned int *hours,
                    unsigned int *minutes,
                    unsigned int *seconds) {

    const long number_seconds_in_a_day = 86400;
    const long number_seconds_in_an_hour = 3600;

    /* Support variable */
    unsigned long remaining_seconds = 0;

    /*
     * We bring back the total number of seconds
     * to the interval [0, 86400]
     */
    number_seconds %= number_seconds_in_a_day;

    /*
     * We calculate the number of hours and save the number
     * of excess seconds
     */
    remaining_seconds = number_seconds % number_seconds_in_an_hour;
    *hours = (number_seconds - remaining_seconds) / number_seconds_in_an_hour;

    /*
     * We calculate the number of minutes and save the number
     * of excess seconds
     */
    *seconds = remaining_seconds % 60;
    *minutes = (remaining_seconds - *seconds) / 60;
}

Complete Program

Let's now write a complete program that requests a number of seconds from the user and prints the corresponding number of hours, minutes, and seconds:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <stdio.h>

void time_calculation(unsigned long number_seconds,
                    unsigned int *hours,
                    unsigned int *minutes,
                    unsigned int *seconds);

int main() {
    unsigned long number_seconds = 0;

    /* Variables for time calculation */
    unsigned int hours = 0;
    unsigned int minutes = 0;
    unsigned int seconds = 0;

    /* Asks the user to enter a number of seconds */
    printf("Enter a number of seconds: ");
    scanf("%lu", &number_seconds);

    /* Calculates the time */
    time_calculation(number_seconds, &hours, &minutes, &seconds);

    /* Prints the time */
    printf("%lu seconds correspond to %u hours, %u minutes and %u seconds\n",
           number_seconds, hours, minutes, seconds);

    return 0;
}

void time_calculation(unsigned long number_seconds,
                    unsigned int *hours,
                    unsigned int *minutes,
                    unsigned int *seconds) {

    const long number_seconds_in_a_day = 86400;
    const long number_seconds_in_an_hour = 3600;

    /* Support variable */
    unsigned long remaining_seconds = 0;

    /*
     * We bring back the total number of seconds
     * to the interval [0, 86400]
     */
    number_seconds %= number_seconds_in_a_day;

    /*
     * We calculate the number of hours and save the number
     * of excess seconds
     */
    remaining_seconds = number_seconds % number_seconds_in_an_hour;
    *hours = (number_seconds - remaining_seconds) / number_seconds_in_an_hour;

    /*
     * We calculate the number of minutes and save the number
     * of excess seconds
     */
    *seconds = remaining_seconds % 60;
    *minutes = (remaining_seconds - *seconds) / 60;
}

Compiling and executing the program, let's try to pass the number 41130 which corresponds to 11 hours, 30 minutes and 25 seconds:

Enter a number of seconds: 41130
41130 seconds correspond to 11 hours, 25 minutes and 30 seconds

Trying to enter a number greater than 86400, for example 192441, we obtain the following result:

Enter a number of seconds: 192441
192441 seconds correspond to 5 hours, 27 minutes and 21 seconds

The result is correct since 192441 seconds correspond to 2 days, 5 hours, 27 minutes and 21 seconds. If we subtract from this number the number of seconds that correspond to 2 days, we obtain:

192441 - (86400 \cdot 2) = 19641

Trying to pass this value to our program, we obtain:

Enter a number of seconds: 19641
19641 seconds correspond to 5 hours, 27 minutes and 21 seconds

That is, the result we obtained before.