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!
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.
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.
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.
Steps to convert hours, minutes, seconds to seconds:Multiply hours by 3600. Multiple minutes by 60. Add all the numbers to the seconds variable.
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]]
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)
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With