Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert time string expressed as <number>[m|h|d|s|w] to seconds in Python

Is there a good method to convert a string representing time in the format of [m|h|d|s|w] (m= minutes, h=hours, d=days, s=seconds w=week) to number of seconds? I.e.

def convert_to_seconds(timeduration):
    ...

convert_to_seconds("1h")
-> 3600

convert_to_seconds("1d")
-> 86400

etc?

Thanks!

like image 874
Andrew Avatar asked Jun 22 '10 20:06

Andrew


People also ask

How do you convert strings to seconds in Python?

Use the total_seconds() method of a timedelta object to get the number of seconds since the epoch. Use the timestamp() method. If your Python version is greater than 3.3 then another way is to use the timestamp() method of a datetime class to convert datetime to seconds.

How do I convert time to number in Python?

In this method, we are using strftime() function of datetime class which converts it into the string which can be converted to an integer using the int() function. Returns : It returns the string representation of the date or time object. Code: Python3.

How do you convert string to time in Python?

We can convert a string to datetime using strptime() function. This function is available in datetime and time modules to parse a string to datetime and time objects respectively.

How do you convert hours minutes seconds to seconds in Python?

Steps to convert hours, minutes, seconds to seconds:Multiply hours by 3600. Multiple minutes by 60. Add all the numbers to the seconds variable.


4 Answers

Yes, there is a good simple method that you can use in most languages without having to read the manual for a datetime library. This method can also be extrapolated to ounces/pounds/tons etc etc:

seconds_per_unit = {"s": 1, "m": 60, "h": 3600, "d": 86400, "w": 604800}

def convert_to_seconds(s):
    return int(s[:-1]) * seconds_per_unit[s[-1]]
like image 195
John Machin Avatar answered Oct 05 '22 16:10

John Machin


I recommend using the timedelta class from the datetime module:

from datetime import timedelta

UNITS = {"s":"seconds", "m":"minutes", "h":"hours", "d":"days", "w":"weeks"}

def convert_to_seconds(s):
    count = int(s[:-1])
    unit = UNITS[ s[-1] ]
    td = timedelta(**{unit: count})
    return td.seconds + 60 * 60 * 24 * td.days

Internally, timedelta objects store everything as microseconds, seconds, and days. So while you can give it parameters in units like milliseconds or months or years, in the end you'll have to take the timedelta you created and convert back to seconds.

In case the ** syntax confuses you, it's the Python apply syntax. Basically, these function calls are all equivalent:

def f(x, y): pass

f(5, 6)
f(x=5, y=6)
f(y=6, x=5)

d = {"x": 5, "y": 6}
f(**d)
like image 21
Eli Courtwright Avatar answered Oct 05 '22 16:10

Eli Courtwright


And another to add to the mix. This solution is brief, but fairly tolerant, and allows for multiples, such as 10m 30s

from datetime import timedelta
import re

UNITS = {'s':'seconds', 'm':'minutes', 'h':'hours', 'd':'days', 'w':'weeks'}

def convert_to_seconds(s):
    return int(timedelta(**{
        UNITS.get(m.group('unit').lower(), 'seconds'): float(m.group('val'))
        for m in re.finditer(r'(?P<val>\d+(\.\d+)?)(?P<unit>[smhdw]?)', s, flags=re.I)
    }).total_seconds())

Test results:

>>> convert_to_seconds('10s')
10
>>> convert_to_seconds('1')  # defaults to seconds
1
>>> convert_to_seconds('1m 10s')  # chaining
70
>>> convert_to_seconds('1M10S')  # case insensitive
70
>>> convert_to_seconds('1week 3days')  # ignores 'eek' and 'ays'
864000
>>> convert_to_seconds('This will take 1.25min, probably.')  # floats
75

not perfect

>>> convert_to_seconds('1month 3days')  # actually 1minute + 3 days
259260
>>> convert_to_seconds('40s 10s')  # 1st value clobbered by 2nd
10
like image 45
FraggaMuffin Avatar answered Oct 05 '22 18:10

FraggaMuffin


I usually need to support raw numbers, string numbers and string numbers ending in [m|h|d|s|w].

This version will handle: 10, "10", "10s", "10m", "10h", "10d", "10w".

Hat tip to @Eli Courtwright's answer on the string conversion.

UNITS = {"s":"seconds", "m":"minutes", "h":"hours", "d":"days", "w":"weeks"}

def convert_to_seconds(s):
    if isinstance(s, int):
        # We are dealing with a raw number
        return s

    try:
        seconds = int(s)
        # We are dealing with an integer string
        return seconds
    except ValueError:
        # We are dealing with some other string or type
        pass

    # Expecting a string ending in [m|h|d|s|w]
    count = int(s[:-1])
    unit = UNITS[ s[-1] ]
    td = timedelta(**{unit: count})
    return td.seconds + 60 * 60 * 24 * td.days
like image 24
rouble Avatar answered Oct 05 '22 18:10

rouble