简体   繁体   中英

Convert time input to a float to enable math functions in C++

I am asking the user to input a start time and an end time in this format: 15.45 (military time with a decimal instead of a colon) and I need to convert those times to a float to perform calculations on them. I am having trouble wrapping my mind around converting the 60 minutes of an hour to a decimal value. eg - User inputs start of 12.45 and end of 14.15, this should be converted to 12.75 and 14.25 respectively. How would I go about this conversion?

Also, something I believe I am more capable of figuring out, but curious anyway: how would I validate input so as not to allow a time greater than 23.59 and no time with the last two digits greater than 59?

just use

double time = hours + minutes / 60.0;
bool hoursValid = hours < 24; // hours are unsigned, right?
bool minutesValid = minutes < 60;

Example:

char buf[] = "9.45";
unsigned int hours, minutes;
sscanf(buf, "%d.%d", &hours, &minutes);
printf("%f", hours + minutes/60.0); // outputs 9.75

If you get double 9.45 as input, you need to #include <cmath> and split it as

hours = floor(v);
minutes = (v - hours) * 100;

As soon as one of the values is double , then the arithmetic will be done in double , with double results. So you can convert the minutes to double , using any of the three C++ syntaxes: static_cast<double>(minutes) , double(minutes) or (double)minutes , or just divide by 60.0 , rather than the integer 60 . (I like to be explicit, so I'd write double(minutes) / 60.0 . And some people prefer static_cast , even in this case.)

With regards to the validation, I'd do it before conversion; once you've added the minutes to the hours, it's too late anyway.

You have to separate the integer and decimal components of the number. You will keep the integer part intact, then add the decimal part divided by 60 to it.

Validation is also simple once you separate into hours and minutes.

I'm going to assume your code reads the value in from the user as a string. You will need to parse the user input at the decimal point to get the hours and minutes as two separate values. Once you have that, then you can convert minutes into a fraction of an hour and add it to the number of hours.

bool military_time_valid(float a) {
    int t = (int)a;
    if (t >= 24)
        throw std::runtime_error("invalid hours");
    if (a-t >= .6)
        throw std::runtime_error("invalid minutes");
}
float military_to_decimal(float a) {
    int t = (int)a;
    return t + (a-t)/.6;
}
float decimal_to_military(float a) {
    int t = (int)a;
    return t + (a-t)*.6;
}
float t = 15.45;
int h = (int) t;
float m = 100 * (t - h);
printf("%f", h + m / 60);

gives output: 15.750000

Check if h is between 0 and 23 and m is between 0 and 59 .

Is there some reason you don't want to create a MilTime class and overload the arithmetic operators? That would save you from having to convert to/from all the time, and would more clearly state your intentions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM