如何用Python计算两个UNIX时间戳的可读差异?
这个问题和关于用Python计算日期差的那个问题有点相似,但不完全一样。我不是在处理字符串,而是需要计算两个时间戳之间的差异,并把这个差异转换成易于理解的格式。
比如:
32 Seconds
17 Minutes
22.3 Hours
1.25 Days
3.5 Weeks
2 Months
4.25 Years
另外,我想把差异表达成这样的形式:
4 years, 6 months, 3 weeks, 4 days, 6 hours 21 minutes and 15 seconds
我觉得我不能用strptime
,因为我是在处理两个时间戳之间的差异。我可以自己写代码来实现这个功能,但我很确定已经有现成的东西可以用。
请问哪个模块比较合适?我是不是在time
模块里漏掉了什么?我刚开始学习Python,如果这个问题确实是重复的,那是因为我没能找到合适的搜索关键词。
补充说明
为了准确起见,我最关心的是当前年份的日历。
8 个回答
24
今天我也遇到了同样的问题,找了半天也没找到标准库里能用的东西,所以我写了这个:
#!/usr/bin/env python
INTERVALS = [1, 60, 3600, 86400, 604800, 2419200, 29030400]
NAMES = [('second', 'seconds'),
('minute', 'minutes'),
('hour', 'hours'),
('day', 'days'),
('week', 'weeks'),
('month', 'months'),
('year', 'years')]
def humanize_time(amount, units):
"""
Divide `amount` in time periods.
Useful for making time intervals more human readable.
>>> humanize_time(173, 'hours')
[(1, 'week'), (5, 'hours')]
>>> humanize_time(17313, 'seconds')
[(4, 'hours'), (48, 'minutes'), (33, 'seconds')]
>>> humanize_time(90, 'weeks')
[(1, 'year'), (10, 'months'), (2, 'weeks')]
>>> humanize_time(42, 'months')
[(3, 'years'), (6, 'months')]
>>> humanize_time(500, 'days')
[(1, 'year'), (5, 'months'), (3, 'weeks'), (3, 'days')]
"""
result = []
unit = map(lambda a: a[1], NAMES).index(units)
# Convert to seconds
amount = amount * INTERVALS[unit]
for i in range(len(NAMES)-1, -1, -1):
a = amount / INTERVALS[i]
if a > 0:
result.append( (a, NAMES[i][1 % a]) )
amount -= a * INTERVALS[i]
return result
if __name__ == "__main__":
import doctest
doctest.testmod()
你可以用 dateutil.relativedelta()
来计算准确的时间差,然后用这个脚本把它变得更容易理解。
57
这是对 @Schnouki 的解决方案的小改进,使用了一行代码就能完成列表的生成。同时,它还会在有多个实体(比如小时)时显示复数形式。
导入 relativedelta
>>> from dateutil.relativedelta import relativedelta
一个 lambda 函数
>>> attrs = ['years', 'months', 'days', 'hours', 'minutes', 'seconds']
>>> human_readable = lambda delta: ['%d %s' % (getattr(delta, attr), attr if getattr(delta, attr) > 1 else attr[:-1])
... for attr in attrs if getattr(delta, attr)]
使用示例:
>>> human_readable(relativedelta(minutes=125))
['2 hours', '5 minutes']
>>> human_readable(relativedelta(hours=(24 * 365) + 1))
['365 days', '1 hour']
64
你可以使用很棒的 dateutil 模块和它的 relativedelta 类:
import datetime
import dateutil.relativedelta
dt1 = datetime.datetime.fromtimestamp(123456789) # 1973-11-29 22:33:09
dt2 = datetime.datetime.fromtimestamp(234567890) # 1977-06-07 23:44:50
rd = dateutil.relativedelta.relativedelta (dt2, dt1)
print "%d years, %d months, %d days, %d hours, %d minutes and %d seconds" % (rd.years, rd.months, rd.days, rd.hours, rd.minutes, rd.seconds)
# 3 years, 6 months, 9 days, 1 hours, 11 minutes and 41 seconds
这个类不计算周数,不过这应该不难加上。