可读时间格式(语法好!)



我一直在阅读转换输入秒数的方法的帖子,该方法应该以给定持续时间(小时,分钟,秒)的形式字符串输出。但我想知道如何格式化它,以便它考虑到单数/复数,例如,当我知道,62秒应该读为"1 minute and 2 seconds",而120秒应该读为"2 minutes"

另一个标准是,如果秒是0,它应该返回"now"

下面是目前为止的代码:
def format_duration(seconds, granularity = 2):
    intervals = (('hours', 3600), ('minutes', 60), ('seconds', 1))
    human_time = []
    for name, count in intervals: 
        value = seconds // count
        if value: 
            seconds -= value * count
            if value == 1:
                name = name.rstrip('s')
            human_time.append("{} {}".format(value, name))
        else:
            return "now"
    return ','.join(human_time[:granularity])

请帮忙!谢谢!

MJ

你的代码已经很好地工作了,你只是有一个问题与你的return "now",我在下面的代码中修复。你还希望你的代码做什么?

def prettyList(human_time):
    if len(human_time) > 1:
        return ' '.join([', '.join(human_time[:-1]), "and", human_time[-1]])
    elif len(human_time) == 1:
        return human_time[0]
    else:
        return ""
def format_duration(seconds, granularity = 2):
    intervals = (('hours', 3600), ('minutes', 60), ('seconds', 1))
    human_time = []
    for name, count in intervals: 
        value = seconds // count
        if value: 
            seconds -= value * count
            if value == 1:
                name = name.rstrip('s')
            human_time.append("{} {}".format(value, name))
    if not human_time:
        return "now"
    human_time = human_time[:granularity]
    return prettyList(human_time)

编辑:所以我添加了一个函数来美化输出,列表中的最后一项将用"and"分隔,所有其他项将用逗号分隔。即使您在代码中添加了更多的间隔(如('days', 86400)),这仍然可以工作。输出现在看起来像2 hours, 1 minute and 43 seconds25 minutes and 14 seconds

对可读性做了一些调整:

def pretty_list(human_time):
    return human_time[0] if len(human_time) == 1 else ' '.join([', '.join(human_time[:-1]), "and", human_time[-1]])

def get_intervals(seconds):
    m, s = divmod(seconds, 60)
    h, m = divmod(m, 60)
    return (
        ("hour", h),
        ("minute", m),
        ("second", s)
    )

def format_duration(seconds, granularity=3):
    intervals = get_intervals(seconds)
    human_time = []
    for name, value in intervals:
        if value == 0:
            continue
        elif value == 1:
            human_time.append("{} {}".format(value, name))
        else:
            human_time.append("{} {}s".format(value, name))
    return (pretty_list(human_time[:granularity])) if len(human_time) != 0 else "now"

您可以尝试为每个变体编写代码:

def timestamp(ctime):
    sec = int(ctime)
    if sec == 0:
        return "Now"
    m, s = divmod(sec, 60)
    h, m = divmod(m, 60)
    if h == 1: hr_t = 'Hour'
    else: hr_t = 'Hours'
    if m == 1: mn_t = 'Minute'
    else: mn_t = 'Minutes'
    if s == 1: sc_t = 'Second'
    else: sc_t = 'Seconds'
    time_stamp = ""
    if h > 0 and m ==0 and s ==0:
        time_stamp = "%02d %s " % (h, hr_t)
    elif h > 0:
        time_stamp = "%02d %s, " % (h, hr_t)
    if m > 0 and s !=0:
        time_stamp = time_stamp +"%02d %s and %02d %s" % (m, mn_t, s, sc_t)
    elif m > 0 and s == 0:
        time_stamp = time_stamp +"%02d %s" % (m, mn_t)
    elif m == 0  and s != 0:
        time_stamp = time_stamp +"%02d %s" % (s, sc_t)
    return time_stamp
print (timestamp(11024))
print (timestamp(0))
print (timestamp(31))
print (timestamp(102))
print (timestamp(61))
print (timestamp(60))
print (timestamp(3600))
print (timestamp(3632))
03 Hours, 03 Minutes and 44 Seconds
Now
31 Seconds
01 Minute and 42 Seconds
01 Minute and 01 Second
01 Minute
01 Hour 
01 Hour, 32 Seconds

或者你可以使用dateutil中的relativedelta选项,然后把骨头从里面挑出来。

from dateutil.relativedelta import relativedelta
attrs = ['years', 'months', 'days', 'hours', 'minutes', 'seconds']
human_readable = lambda delta: ['%d %s ' % (getattr(delta, attr), getattr(delta, attr) != 1 and attr   or attr[:-1]) for attr in attrs if getattr(delta, attr) or attr == attrs[-1]]
readable=''
for i in human_readable(relativedelta(seconds=1113600)):
    readable += i
print readable
print human_readable(relativedelta(seconds=13600))
print human_readable(relativedelta(seconds=36))
print human_readable(relativedelta(seconds=60))
print human_readable(relativedelta(seconds=3600))
12 days 21 hours 20 minutes 0 seconds 
['3 hours ', '46 minutes ', '40 seconds ']
['36 seconds ']
['1 minute ', '0 seconds ']
['1 hour ', '0 seconds ']

有关第二个示例的更多示例,请参见:http://code.activestate.com/recipes/578113-human-readable-format-for-a-given-time-delta/这就是我从

中窃取的几乎所有第二组代码

我找到了!我实际上需要更多的间隔时间——要求的持续时间比我想象的要长……

def prettyList(human_time):
    if len(human_time) > 1:
        return ' '.join([', '.join(human_time[:-1]), "and", human_time[-1]])
    elif len(human_time) == 1:
        return human_time[0]
    else:
        return ""
def format_duration(seconds, granularity = 4):
    intervals = (('years', 29030400), ('months', 2419200), ('weeks', 604800),('days', 86400),('hours', 3600), ('minutes', 60), ('seconds', 1))
    human_time = []
    for name, count in intervals: 
        value = seconds // count
        if value: 
            seconds -= value * count
            if value == 1:
                name = name.rstrip('s')
            human_time.append("{} {}".format(value, name))
    if not human_time:
        return "now"
    human_time = human_time[:granularity]
    return prettyList(human_time)

我想我已经涵盖了所有的基础,但我相信有人会告诉我,如果我犯了一个错误(或大或小):)

from dateutil.relativedelta import relativedelta
def convertdate(secs):
    raw_date = relativedelta(seconds=secs)
    years, days = divmod(raw_date.days, 365) # To crudely cater for leap years / 365.2425
    hours = raw_date.hours
    minutes = raw_date.minutes
    seconds = raw_date.seconds
    full = [years,days,hours,minutes,seconds]
    date_text=['','','','','']
    if years == 1: date_text[0] = "Year"
    else: date_text[0] = "Years"
    if days == 1: date_text[1] = "Day"
    else: date_text[1] = "Days"
    if hours == 1: date_text[2] = "Hour"
    else: date_text[2] = "Hours"
    if minutes == 1: date_text[3] = "Minute"
    else: date_text[3] = "Minutes"
    if seconds == 1: date_text[4] = "Second"
    else: date_text[4] = "Seconds"
    first_pos = 0
    final_pos = 0
    element_count = 0
    # Find the first and final set positions and the number of returned values
    for i in range(5):
        if full[i] != 0:
            final_pos = i
            element_count +=1
            if first_pos == 0:
                first_pos = i
    # Return "now" and any single value
    if element_count == 0:
        return "Now"
    if element_count == 1:
        return "%02d %s" % (full[final_pos],date_text[final_pos])
    # Initially define the separators
    separators=['','','','','']
    ret_str=''
    for i in range(4):
        if full[i] != 0:
            separators[i] = ', '
    separators[final_pos] = ''
    # Redefine the final separator
    for i in range(4,-1,-1):
        if separators[i] == ', ':
            separators[i] = ' and '
            break
    #Build the readable formatted time string
    for i in range(5):
        if full[i] != 0:
            ret_str += "%02d %s%s" % (full[i],date_text[i],separators[i])
    return ret_str
print convertdate(1111113601)
print convertdate(1111113635)
print convertdate(1111113600)
print convertdate(1111111200)
print convertdate(1111104000)
print convertdate(1111104005)
print convertdate(11113240)
print convertdate(11059240)
print convertdate(11113600)
print convertdate(36)
print convertdate(60)
print convertdate(61)
print convertdate(121)
print convertdate(122)
print convertdate(120)
print convertdate(3600)
print convertdate(3601)
35 Years, 85 Days, 02 Hours, 40 Minutes and 01 Second
35 Years, 85 Days, 02 Hours, 40 Minutes and 35 Seconds
35 Years, 85 Days, 02 Hours and 40 Minutes
35 Years, 85 Days and 02 Hours
35 Years and 85 Days
35 Years, 85 Days and 05 Seconds
128 Days, 15 Hours and 40 Seconds
128 Days and 40 Seconds
128 Days, 15 Hours, 06 Minutes and 40 Seconds
36 Seconds
01 Minute
01 Minute and 01 Second
02 Minutes and 01 Second
02 Minutes and 02 Seconds
02 Minutes
01 Hour
01 Hour and 01 Second

相关内容

  • 没有找到相关文章

最新更新