在Python中将表示为<number> [m | h | d | s | w]的时间字符串转换为秒

And*_*rew 8 python datetime

是否有一种很好的方法来转换表示时间的字符串,格式为[m | h | d | s | w](m =分钟,h =小时,d =天,s =秒w =星期)到秒数?即

def convert_to_seconds(timeduration):
    ...

convert_to_seconds("1h")
-> 3600

convert_to_seconds("1d")
-> 86400
Run Code Online (Sandbox Code Playgroud)

等等?

谢谢!

Joh*_*hin 18

是的,有一个很好的简单方法,您可以在大多数语言中使用,而无需阅读日期时间库的手册.这种方法也可以外推到盎司/磅/吨等等:

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]]
Run Code Online (Sandbox Code Playgroud)


Eli*_*ght 9

我建议使用datetime模块中的timedelta类:

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
Run Code Online (Sandbox Code Playgroud)

在内部,timedelta对象将所有内容存储为微秒,秒和天.因此,虽然您可以以毫秒或数月或数年为单位给出参数,但最终您必须将timedelta您创建并转换回秒.

如果**语法让您感到困惑,那就是Python apply语法.基本上,这些函数调用都是等效的:

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)
Run Code Online (Sandbox Code Playgroud)


Fra*_*fin 8

还有另一个要添加到混合中。这个解决方案很简短,但相当宽容,并且允许多个,例如10m 30s

from datetime import timedelta
import re

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

def convert_to_seconds(text):
    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]?)',
            text.replace(' ', ''),
            flags=re.I
        )
    }).total_seconds())
Run Code Online (Sandbox Code Playgroud)

检测结果:

>>> 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
Run Code Online (Sandbox Code Playgroud)

不完美

>>> convert_to_seconds('1 month 3 days')  # actually 1min 3days
259260
>>> convert_to_seconds('40s 10s')  # 1st value clobbered by 2nd
10
>>> convert_to_seconds('cook for 3 to 5 minutes')  # is not intelligent
303
Run Code Online (Sandbox Code Playgroud)