Home > OS >  Convert minutes to full hours without days
Convert minutes to full hours without days

Time:01-03

For heavy machinery, one often needs to know the number of hours a machine ran. I have a dataframe with start times and end times. For each time the machine is used, I calculate the minutes the machine was used. This results in a column df['minutes'].

How do I convert minutes to hours? For 3,346 minutes, I should get 55 hours and 46 minutes, or 55:46.

Use this as a working example:

df = pd.DataFrame(columns = ['minutes'], data =[3346])
  • If I use this, I get 07:46:

      df['duration'] = pd.to_datetime(df['minutes'], unit='m').dt.strftime('%H:%M')
    
  • If I use this, I get 03 07:46 07:46:

      df['duration'] = pd.to_datetime(df['minutes'], unit='m').dt.strftime('%d %H:%M')
    

    Why the three (03)?

  • I also tried to use apply and gmtime to the column of minutes, which returns 03 07:46:

      def dur_time1(x):
          x*=60
          x = time.gmtime(x)
          x = time.strftime("%d %H:%M", x)
          return x
    
      df['duration'] = df['minutes'].apply(dur_time1)
    
  • Lastly, I tried to use apply and timedelta to the column of minutes, which returns 2 days 07:46:00:

      def dur_time2(x):
          x*=60
          x = timedelta(seconds = x)
          return x
    
      df['duration'] = df['minutes'].apply(dur_time2)
    

    I can live with the 2 days, which I can split off and multiply by 24. But that seems convoluted.

But none of these solutions show 55 hours and 46 minutes.

CodePudding user response:

you could use this function :

def minutes_to_hours(minutes : int):
    time = '{}:{}'.format(minutes//60,minutes`)
    return time 

output :

55:46

CodePudding user response:

There is absolutely no issues with your results. Python did just what you wanted it to do.

Case 1: You asked python to give you the hours and minutes in the time component.

df['duration'] = pd.to_datetime(df['minutes'], unit='m').dt.strftime('%H:%M')

Case 2: You asked python to give you the days, hours and minutes in the time component.

pd.to_datetime(df['minutes'], unit='m').dt.strftime('%d %H:%M')

From documentation %d does the following; enter image description here

python is a C compiler. in C tm_mday starts from 1 to find the next/previous days. Simply put;

strftime() takes an
       argument of data type time_t, which represents calendar time.
       When interpreted as an absolute time value, it represents the
       number of seconds elapsed since the Epoch, 1970-01-01 00:00:00
        0000 (UTC)

In your case, because you have 55.766667 hours in this time component, strftime('%d %H:%M') is interpreting it as 3rd day, 7th Hour 46th Minute since the Epoch, 1970-01-01 00:00:00 0000 (UTC). If you change it to pd.to_datetime(df['minutes'], unit='m').dt.strftime('%d %I:%M'), you realise it pads it with a 0.

If you wanted to find the exact time component count, please use numpy's Datetime Units

df['minutes'].astype('timedelta64[m]')/60

As explained, the time span in numpy's datetime unit is the range of a 64-bit integer times the length of the date or unit. That is the the time span for ‘D’ (day) is exactly 24 times longer than the time span for ‘h’ (hour) which conditions it to convert the minutes into exact time components

CodePudding user response:

divmod is also an option:

def minutes_to_hours(minutes: int):
    return '{}:{}'.format(*divmod(minutes,60))

CodePudding user response:

You could use the divmod function:

In [1]: import pandas as pd

In [2]: def minutes_to_hour_representation(minutes: int) -> str:
   ...:     hours, remaining_mins = divmod(minutes, 60)
   ...:     return f'{hours:02}:{remaining_mins:02}'
   ...: 

In [3]: df = pd.DataFrame(columns=['minutes'], data=[3346, 36, 66])

In [4]: df
Out[4]: 
   minutes
0     3346
1       36
2       66

In [5]: df['hours'] = df['minutes'].map(lambda m: minutes_to_hour_representation(m))

In [6]: df
Out[6]: 
   minutes  hours
0     3346  55:46
1       36  00:36
2       66  01:06
  • Related