【问题标题】:How do I convert seconds to hours, minutes and seconds?如何将秒转换为小时、分钟和秒?
【发布时间】:2014-10-01 08:11:14
【问题描述】:

我有一个以秒为单位返回信息的函数,但我需要以小时:分钟:秒的形式存储该信息。

有没有一种简单的方法可以在 Python 中将秒转换为这种格式?

【问题讨论】:

标签: python datetime


【解决方案1】:

通过使用divmod() 函数,它只进行一次除法即可产生商和余数,您只需两个数学运算即可非常快速地得到结果:

m, s = divmod(seconds, 60)
h, m = divmod(m, 60)

然后使用string formatting将结果转换成你想要的输出:

print('{:d}:{:02d}:{:02d}'.format(h, m, s)) # Python 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+

【讨论】:

  • 如果您更喜欢运算符而不是函数,请使用模;例如(仅分钟/秒):'%d:%02dmn' % (seconds / 60, seconds % 60)
  • 你可以将它延长到几天:d, h = divmod(h, 24).
  • @MarkRansom: 然后到几个月m, d = divmod(m, 31)。哎呀,不,你不能。更糟糕的是,如果闰秒进入游戏,你的代码就会出错。长话短说:使用timedelta,不要弄乱日历,它会咬你的。
  • @Tibo timedelta 处理闰秒吗?我怀疑不是。在很多应用中,这个简单的数学运算就绰绰有余了。
  • 对于那些讨论日期时间的人:请注意,原始问题不希望将小时分解为任何更大的时间单位,因此任何创建比小时更大的时间单位的东西都需要手动将它们减少回整数小时数。
【解决方案2】:

你可以使用datetime.timedelta函数:

>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'

【讨论】:

  • 这是最好的方法,恕我直言,因为您可以在 timedelta 和任何日期时间对象上使用算术。
  • 这适用于多天:str(datetime.timedelta(seconds=60*60*24+1)) = '1 day, 0:00:01'
  • str(datetime.timedelta(seconds=round(666666.55))) 正确呈现天数;抑制小数秒。
  • timedelta 不是溢出安全的,不能正确执行数学运算,例如str(timedelta(hours=8) - timedelta(hours=10)) 结果是 '-1 day, 22:00:00',而基于整数的解决方案正好适用于您需要 '-02:00:00' 的情况。
  • +1。这个答案可以很容易地修改。例如,如果您想在打印时省略某个字段,请使用:stackoverflow.com/questions/7999935/…
【解决方案3】:

我很难说出一个简单的方法(至少我不记得语法),但可以使用time.strftime,它可以更好地控制格式:

from time import strftime
from time import gmtime

strftime("%H:%M:%S", gmtime(666))
'00:11:06'

strftime("%H:%M:%S", gmtime(60*60*24))
'00:00:00'

gmtime 用于将秒转换为strftime() 需要的特殊元组格式。

注意:在 23:59:59 之后截断

【讨论】:

  • 不幸的是,此方法从 1 开始测量天数,因此它并非旨在表示时间增量,因此这是一个等待发生的意外。例如time.strftime('%d %H:%M:%S', time.gmtime(1)) => '1 day, 0:00:01'。
【解决方案4】:

使用datetime:

使用':0>8' 格式:

from datetime import timedelta

"{:0>8}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{:0>8}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{:0>8}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

没有':0>8' 格式:

"{}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

使用time:

from time import gmtime
from time import strftime

# NOTE: The following resets if it goes over 23:59:59!

strftime("%H:%M:%S", gmtime(125))
# Result: '00:02:05'

strftime("%H:%M:%S", gmtime(60*60*24-1))
# Result: '23:59:59'

strftime("%H:%M:%S", gmtime(60*60*24))
# Result: '00:00:00'

strftime("%H:%M:%S", gmtime(666777))
# Result: '17:12:57'
# Wrong

【讨论】:

  • 如果增量小于一秒则失败:"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
  • 致其他所有人:without ':0>8': 示例缺少前导 0。{:0>8} 向左填充 8 个零。
  • 在 python 3.5.2 中,我得到一个 TypeError。我正在格式化 time.time()-start 变量。有什么见解吗? TypeError: non-empty format string passed to object.__format__
  • 我尝试使用 datetime.now() 而不是 time.time() 来生成我的 timedelta 对象,但我得到了同样的错误。
  • @medley56 使用 Python3 时,如果要使用 0>8:"{:0>8}".format(str(datetime.timedelta(seconds=666777))) 等格式,则需要使用 str()。查看this answer了解更多信息。
【解决方案5】:

这就是我得到它的方式。

def sec2time(sec, n_msec=3):
    ''' Convert seconds to 'D days, HH:MM:SS.FFF' '''
    if hasattr(sec,'__len__'):
        return [sec2time(s) for s in sec]
    m, s = divmod(sec, 60)
    h, m = divmod(m, 60)
    d, h = divmod(h, 24)
    if n_msec > 0:
        pattern = '%%02d:%%02d:%%0%d.%df' % (n_msec+3, n_msec)
    else:
        pattern = r'%02d:%02d:%02d'
    if d == 0:
        return pattern % (h, m, s)
    return ('%d days, ' + pattern) % (d, h, m, s)

一些例子:

$ sec2time(10, 3)
Out: '00:00:10.000'

$ sec2time(1234567.8910, 0)
Out: '14 days, 06:56:07'

$ sec2time(1234567.8910, 4)
Out: '14 days, 06:56:07.8910'

$ sec2time([12, 345678.9], 3)
Out: ['00:00:12.000', '4 days, 00:01:18.900']

【讨论】:

  • 与上面的答案相比,这有什么优势? str(datetime.timedelta(seconds=666))
  • @RiazRizvi 为 666.0666.1 值提供一致的字符串长度(以微秒计)。
【解决方案6】:

如果需要获取datetime.time的值,可以使用这个技巧:

my_time = (datetime(1970,1,1) + timedelta(seconds=my_seconds)).time()

您不能将timedelta 添加到time,但可以将其添加到datetime

UPD:同一技术的另一种变体:

my_time = (datetime.fromordinal(1) + timedelta(seconds=my_seconds)).time()

您可以使用大于 0 的任何数字代替 1。这里我们使用 datetime.fromordinal 将始终返回 datetime 对象且 time 组件为零的事实。

【讨论】:

    【解决方案7】:

    这是我的快速技巧:

    from humanfriendly import format_timespan
    secondsPassed = 1302
    format_timespan(secondsPassed)
    # '21 minutes and 42 seconds'
    

    欲了解更多信息,请访问: https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan

    【讨论】:

    • 你不知道我寻找这个答案有多久了。太感谢了。我希望我能给你的不仅仅是 +1。
    • 太棒了。即使秒数很大时也能完美调整(604800 变为 1 week)。
    【解决方案8】:

    dateutil.relativedelta 如果您还需要以浮点数形式访问小时、分钟和秒,则非常方便。 datetime.timedelta 没有提供类似的接口。

    from dateutil.relativedelta import relativedelta
    rt = relativedelta(seconds=5440)
    print(rt.seconds)
    print('{:02d}:{:02d}:{:02d}'.format(
        int(rt.hours), int(rt.minutes), int(rt.seconds)))
    

    打印

    40.0
    01:30:40
    

    【讨论】:

    • 我得到的输出与你的不同,这让我认为你有一个错字。您可能打算使用seconds=5440 而不是seconds=5540。不过我喜欢你的回答!
    【解决方案9】:

    以下设置对我有用。

    def sec_to_hours(seconds):
        a=str(seconds//3600)
        b=str((seconds%3600)//60)
        c=str((seconds%3600)%60)
        d=["{} hours {} mins {} seconds".format(a, b, c)]
        return d
    
    
    print(sec_to_hours(10000))
    # ['2 hours 46 mins 40 seconds']
    
    print(sec_to_hours(60*60*24+105))
    # ['24 hours 1 mins 45 seconds']
    

    【讨论】:

    • 你可能应该对 a、b 和 c 进行四舍五入
    • @JeanRavenclaw: abc 是整数——实际上是整数转换为字符串。
    • b, c = divmod(seconds%3600, 60) 会更简洁一些。
    【解决方案10】:
    
    division = 3623 // 3600 #to hours
    division2 = 600 // 60 #to minutes
    print (division) #write hours
    print (division2) #write minutes
    

    PS 我的代码不专业

    【讨论】:

      【解决方案11】:

      您可以将秒除以 60 得到分钟

      import time
      seconds = time.time()
      minutes = seconds / 60
      print(minutes)
      

      当你再次除以 60 时,你会得到小时

      【讨论】:

        【解决方案12】:

        小时 (h) 以秒除以 3600 (60 分钟/小时 * 60 秒/分钟) 计算得到的小时数 (h)

        分钟 (m) 由剩余秒数(小时计算的剩余数,按 %)除以 60(60 秒/分钟)计算得出

        类似地,秒(s)按小时和分钟的余数计算。

        Rest 只是字符串格式!

        def hms(seconds):
            h = seconds // 3600
            m = seconds % 3600 // 60
            s = seconds % 3600 % 60
            return '{:02d}:{:02d}:{:02d}'.format(h, m, s)
        
        print(hms(7500))  # Should print 02h05m00s
        

        【讨论】:

        • 虽然此代码可能会为 OP 的问题提供解决方案,但最好添加有关其工作原理/方式的上下文。这可以帮助未来的用户学习并将这些知识应用到他们自己的代码中。在解释代码时,您也可能会以赞成票的形式从用户那里获得积极的反馈。
        【解决方案13】:

        就我而言,我想实现格式 “HH:MM:SS.fff”。 我是这样解决的:

        timestamp = 28.97000002861023
        str(datetime.fromtimestamp(timestamp)+timedelta(hours=-1)).split(' ')[1][:12]
        '00:00:28.970'
        

        【讨论】:

          【解决方案14】:

          如果您希望将日期上“自午夜以来的秒数”的单个值转换为日期时间对象或带有 HH:MM:SS 的字符串,上述解决方案将起作用,但我登陆此页面是因为我想要在 pandas 的整个数据框列上执行此操作。如果其他人想知道如何一次为多个值执行此操作,那么最终对我有用的是:

           mydate='2015-03-01'
           df['datetime'] = datetime.datetime(mydate) + \ 
                            pandas.to_timedelta(df['seconds_since_midnight'], 's')
          

          【讨论】:

            【解决方案15】:

            这是我一直使用的一种方式:(不管它多么低效)

            seconds = 19346
            def zeroes (num):
                if num < 10: num = "0" + num
                return num
            
            def return_hms(second, apply_zeroes):
                sec = second % 60
                min_ = second // 60 % 60
                hrs = second // 3600
                if apply_zeroes > 0:
                   sec = zeroes(sec)
                   min_ = zeroes(min_)
                   if apply_zeroes > 1:
                       hrs = zeroes(hrs)
                return "{}:{}:{}".format(hrs, min_, sec)
            
            print(return_hms(seconds, 1))
            
            

            结果: 5:22:26

            return_hms() 函数语法

            return_hms() 函数是这样使用的:

            第一个变量(秒)是您要转换为 h:m:s 的秒数。

            第二个变量(apply_zeroes)是格式化:

            0 或更少:不应用任何零

            1:对低于 10 的分钟和秒应用零。

            2 或更多:当值小于 10 时,将零应用于任何值(包括小时)。

            【讨论】:

              【解决方案16】:

              这是一个简单的程序,它读取当前时间并将其转换为以小时、分钟和秒为单位的时间

              import time as tm #import package time
              timenow = tm.ctime() #fetch local time in string format
              
              timeinhrs = timenow[11:19]
              
              t=tm.time()#time.time() gives out time in seconds since epoch.
              
              print("Time in HH:MM:SS format is: ",timeinhrs,"\nTime since epoch is : ",t/(3600*24),"days")
              

              输出是

              Time in HH:MM:SS format is:  13:32:45 
              Time since epoch is :  18793.335252338384 days
              

              【讨论】:

                【解决方案17】:

                有点离题的答案,但可能对某人有用

                    def time_format(seconds: int):
                    if seconds is not None:
                        seconds = int(seconds)
                        d = seconds // (3600 * 24)
                        h = seconds // 3600 % 24
                        m = seconds % 3600 // 60
                        s = seconds % 3600 % 60
                        if d > 0:
                            return '{:02d}D {:02d}H {:02d}m {:02d}s'.format(d, h, m, s)
                        elif h > 0:
                            return '{:02d}H {:02d}m {:02d}s'.format(h, m, s)
                        elif m > 0:
                            return '{:02d}m {:02d}s'.format(m, s)
                        elif s > 0:
                            return '{:02d}s'.format(s)
                    return '-'
                

                结果:

                print(time_format(25*60*60 + 125)) 
                >>> 01D 01H 02m 05s
                print(time_format(17*60*60 + 35)) 
                >>> 17H 00m 35s
                print(time_format(3500)) 
                >>> 58m 20s
                print(time_format(21)) 
                >>> 21s
                

                【讨论】:

                  【解决方案18】:

                  我在这里查看了所有答案,但仍然尝试了自己的答案

                  def a(t):
                    print(f"{int(t/3600)}H {int((t/60)%60) if t/3600>0 else int(t/60)}M {int(t%60)}S")
                  

                  结果:

                  >>> a(7500)
                  2H 5M 0S
                  >>> a(3666)
                  1H 1M 6S
                  

                  Python:3.8.8

                  【讨论】:

                    猜你喜欢
                    • 2015-06-02
                    • 1970-01-01
                    • 2021-10-29
                    相关资源
                    最近更新 更多