将时间字符串<m|h|d|s|w>转换为秒(Python)

25 投票
5 回答
13969 浏览
提问于 2025-04-16 00:18

有没有什么好的方法可以把一个表示时间的字符串,比如说格式是[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

等等?

谢谢!

5 个回答

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())

测试结果:

>>> 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

并不是完美的。

>>> 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
18

我推荐使用来自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

在内部,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)
38

是的,有一种很好的简单方法,你可以在大多数编程语言中使用,而不需要去查阅日期时间库的手册。这个方法也可以扩展到盎司/磅/吨等等:

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]]

撰写回答