Hướng dẫn how do you convert hours to days in python? - làm thế nào để bạn chuyển đổi giờ thành ngày trong python?

Bản vá cũng như câu trả lời của Ralph Bolton.Chuyển đến một lớp và di chuyển TULP của TULP (khoảng thời gian) sang từ điển.Thêm một hàm tròn tùy chọn tùy thuộc vào độ chi tiết (kích hoạt theo mặc định).Sẵn sàng dịch bằng cách sử dụng getText (mặc định là vô hiệu hóa).Đây là ý định tải từ một mô -đun.Đây là cho Python3 (đã thử nghiệm 3.6 - 3.8)

import gettext
import locale
from itertools import chain

mylocale = locale.getdefaultlocale()
# see --> https://stackoverflow.com/a/10174657/11869956 thx 
#localedir = os.path.join(os.path.dirname(__file__), 'locales')
# or python > 3.4:
try:
    localedir = pathlib.Path(__file__).parent/'locales'
    lang_translations = gettext.translation('utils', localedir, 
                                            languages=[mylocale[0]])
    lang_translations.install()
    _ = lang_translations.gettext
except Exception as exc:
    print('Error: unexcept error while initializing translation:', file=sys.stderr)
    print(f'Error: {exc}', file=sys.stderr)
    print(f'Error: localedir={localedir}, languages={mylocale[0]}', file=sys.stderr)
    print('Error: translation has been disabled.', file=sys.stderr)
    _ = gettext.gettext

Đây là lớp học:

class FormatTimestamp:
    """Convert seconds to, optional rounded, time depending of granularity's degrees.
        inspired by https://stackoverflow.com/a/24542445/11869956"""
    def __init__(self):
        # For now i haven't found a way to do it better
        # TODO: optimize ?!? ;)
        self.intervals = {
            # 'years'     :   31556952,  # https://www.calculateme.com/time/years/to-seconds/
            # https://www.calculateme.com/time/months/to-seconds/ -> 2629746 seconds
            # But it's outputing some strange result :
            # So 3 seconds less (2629743) : 4 weeks, 2 days, 10 hours, 29 minutes and 3 seconds
            # than after 3 more seconds : 1 month ?!?
            # Google give me 2628000 seconds
            # So 3 seconds less (2627997): 4 weeks, 2 days, 9 hours, 59 minutes and 57 seconds
            # Strange as well 
            # So for the moment latest is week ...
            #'months'    :   2419200, # 60 * 60 * 24 * 7 * 4 
            'weeks'     :   604800,  # 60 * 60 * 24 * 7
            'days'      :   86400,    # 60 * 60 * 24
            'hours'     :   3600,    # 60 * 60
            'minutes'   :   60,
            'seconds'  :   1
            }
        self.nextkey = {
            'seconds'   :   'minutes',
            'minutes'   :   'hours',
            'hours'     :   'days',
            'days'      :   'weeks',
            'weeks'     :   'weeks',
            #'months'    :   'months',
            #'years'     :   'years' # stop here
            }
        self.translate = {
            'weeks'     :   _('weeks'),
            'days'      :   _('days'),
            'hours'     :   _('hours'),
            'minutes'   :   _('minutes'),
            'seconds'   :   _('seconds'),
            ## Single
            'week'      :   _('week'),
            'day'       :   _('day'),
            'hour'      :   _('hour'),
            'minute'    :   _('minute'),
            'second'    :   _('second'),
            ' and'      :   _('and'),
            ','         :   _(','),     # This is for compatibility
            ''          :   '\0'        # same here BUT we CANNOT pass empty string to gettext 
                                        # or we get : warning: Empty msgid.  It is reserved by GNU gettext:
                                        # gettext("") returns the header entry with
                                        # meta information, not the empty string.
                                        # Thx to --> https://stackoverflow.com/a/30852705/11869956 - saved my day
            }

    def convert(self, seconds, granularity=2, rounded=True, translate=False):
        """Proceed the conversion"""

        def _format(result):
            """Return the formatted result
            TODO : numpy / google docstrings"""
            start = 1 
            length = len(result)
            none = 0
            next_item = False
            for item in reversed(result[:]):
                if item['value']:
                    # if we have more than one item
                    if length - none > 1:
                        # This is the first 'real' item 
                        if start == 1:
                            item['punctuation'] = ''
                            next_item = True
                        elif next_item:
                            # This is the second 'real' item
                            # Happened 'and' to key name
                            item['punctuation'] = ' and'
                            next_item = False
                        # If there is more than two 'real' item
                        # than happened ','
                        elif 2 < start:
                            item['punctuation'] = ','
                        else:
                            item['punctuation'] = ''
                    else:
                        item['punctuation'] = ''
                    start += 1
                else:
                    none += 1
            return [ { 'value'        :   mydict['value'], 
                       'name'         :   mydict['name_strip'],
                       'punctuation'  :   mydict['punctuation'] } for mydict in result \
                                                                  if mydict['value'] is not None ]


        def _rstrip(value, name):
            """Rstrip 's' name depending of value"""
            if value == 1:
                name = name.rstrip('s')
            return name


        # Make sure granularity is an integer
        if not isinstance(granularity, int):
            raise ValueError(f'Granularity should be an integer: {granularity}')

        # For seconds only don't need to compute
        if seconds < 0:
            return 'any time now.'
        elif seconds < 60:
            return 'less than a minute.'

        result = []
        for name, count in self.intervals.items():
            value = seconds // count
            if value:
                seconds -= value * count
                name_strip = _rstrip(value, name)
                # save as dict: value, name_strip (eventually strip), name (for reference), value in seconds
                # and count (for reference)
                result.append({ 
                        'value'        :   value,
                        'name_strip'   :   name_strip,
                        'name'         :   name, 
                        'seconds'      :   value * count,
                        'count'        :   count
                                 })
            else:
                if len(result) > 0:
                    # We strip the name as second == 0
                    name_strip = name.rstrip('s')
                    # adding None to key 'value' but keep other value
                    # in case when need to add seconds when we will 
                    # recompute every thing
                    result.append({ 
                        'value'        :   None,
                        'name_strip'   :   name_strip,
                        'name'         :   name, 
                        'seconds'      :   0,
                        'count'        :   count
                                 })

        # Get the length of the list
        length = len(result)
        # Don't need to compute everything / every time
        if length < granularity or not rounded:
            if translate:
                return ' '.join('{0} {1}{2}'.format(item['value'], _(self.translate[item['name']]), 
                                                _(self.translate[item['punctuation']])) \
                                                for item in _format(result))
            else:
                return ' '.join('{0} {1}{2}'.format(item['value'], item['name'], item['punctuation']) \
                                                for item in _format(result))

        start = length - 1
        # Reverse list so the firsts elements 
        # could be not selected depending on granularity.
        # And we can delete item after we had his seconds to next
        # item in the current list (result)
        for item in reversed(result[:]):
            if granularity <= start <= length - 1:
                # So we have to round
                current_index = result.index(item)
                next_index = current_index - 1
                # skip item value == None
                # if the seconds of current item is superior
                # to the half seconds of the next item: round
                if item['value'] and item['seconds'] > result[next_index]['count'] // 2:
                    # +1 to the next item (in seconds: depending on item count)
                    result[next_index]['seconds'] += result[next_index]['count']
                # Remove item which is not selected
                del result[current_index]
            start -= 1
        # Ok now recalculate everything
        # Reverse as well 
        for item in reversed(result[:]):
            # Check if seconds is superior or equal to the next item 
            # but not from 'result' list but from 'self.intervals' dict
            # Make sure it's not None
            if item['value']:
                next_item_name = self.nextkey[item['name']]
                # This mean we are at weeks
                if item['name'] == next_item_name:
                    # Just recalcul
                    item['value'] = item['seconds'] // item['count']
                    item['name_strip'] = _rstrip(item['value'], item['name'])
                # Stop to weeks to stay 'right' 
                elif item['seconds'] >= self.intervals[next_item_name]:
                    # First make sure we have the 'next item'
                    # found via --> https://stackoverflow.com/q/26447309/11869956
                    # maybe there is a faster way to do it ? - TODO
                    if any(search_item['name'] == next_item_name for search_item in result):
                        next_item_index = result.index(item) - 1
                        # Append to
                        result[next_item_index]['seconds'] += item['seconds']
                        # recalculate value
                        result[next_item_index]['value'] = result[next_item_index]['seconds'] // \
                                                           result[next_item_index]['count']
                        # strip or not
                        result[next_item_index]['name_strip'] = _rstrip(result[next_item_index]['value'],
                                                                       result[next_item_index]['name'])
                    else:
                        # Creating 
                        next_item_index = result.index(item) - 1
                        # get count
                        next_item_count = self.intervals[next_item_name]
                        # convert seconds
                        next_item_value = item['seconds'] // next_item_count
                        # strip 's' or not
                        next_item_name_strip = _rstrip(next_item_value, next_item_name)
                        # added to dict
                        next_item = {
                                       'value'      :   next_item_value,
                                       'name_strip' :   next_item_name_strip,
                                       'name'       :   next_item_name,
                                       'seconds'    :   item['seconds'],
                                       'count'      :   next_item_count
                                       }
                        # insert to the list
                        result.insert(next_item_index, next_item)
                    # Remove current item
                    del result[result.index(item)]
                else:
                    # for current item recalculate
                    # keys 'value' and 'name_strip'
                    item['value'] = item['seconds'] // item['count']
                    item['name_strip'] = _rstrip(item['value'], item['name'])
        if translate:
            return ' '.join('{0} {1}{2}'.format(item['value'], 
                                                _(self.translate[item['name']]), 
                                                _(self.translate[item['punctuation']])) \
                                                for item in _format(result))
        else:
            return ' '.join('{0} {1}{2}'.format(item['value'], item['name'], item['punctuation']) \
                                                for item in _format(result))

Để dùng nó:

myformater = FormatTimestamp()
myconverter = myformater.convert(seconds) 

Độ chi tiết = 1 - 5, tròn = true / false, dịch = true / false

Một số thử nghiệm để hiển thị sự khác biệt:

myformater = FormatTimestamp()
for firstrange in [131440, 563440, 604780, 2419180, 113478160]:
    print(f'#### Seconds : {firstrange} ####')
    print('\tFull - function: {0}'.format(display_time(firstrange, granularity=5)))
    print('\tFull -    class: {0}'.format(myformater.convert(firstrange, granularity=5))) 
    for secondrange in range(1, 6, 1):
        print('\tGranularity   this   answer ({0}): {1}'.format(secondrange, 
                                                             myformater.convert(firstrange,
                                                                                granularity=secondrange, translate=False)))
        print('\tGranularity Bolton\'s answer ({0}): {1}'.format(secondrange, display_time(firstrange,
                                                                                granularity=secondrange)))
    print()
Giây: 131440
    Full - function: 1 day, 12 hours, 30 minutes, 40 seconds
    Full -    class: 1 day, 12 hours, 30 minutes and 40 seconds
    Granularity   this   answer (1): 2 days
    Granularity Bolton's answer (1): 1 day
    Granularity   this   answer (2): 1 day and 13 hours
    Granularity Bolton's answer (2): 1 day, 12 hours
    Granularity   this   answer (3): 1 day, 12 hours and 31 minutes
    Granularity Bolton's answer (3): 1 day, 12 hours, 30 minutes
    Granularity   this   answer (4): 1 day, 12 hours, 30 minutes and 40 seconds
    Granularity Bolton's answer (4): 1 day, 12 hours, 30 minutes, 40 seconds
    Granularity   this   answer (5): 1 day, 12 hours, 30 minutes and 40 seconds
    Granularity Bolton's answer (5): 1 day, 12 hours, 30 minutes, 40 seconds

Giây: 563440

    Full - function: 6 days, 12 hours, 30 minutes, 40 seconds
    Full -    class: 6 days, 12 hours, 30 minutes and 40 seconds
    Granularity   this   answer (1): 1 week
    Granularity Bolton's answer (1): 6 days
    Granularity   this   answer (2): 6 days and 13 hours
    Granularity Bolton's answer (2): 6 days, 12 hours
    Granularity   this   answer (3): 6 days, 12 hours and 31 minutes
    Granularity Bolton's answer (3): 6 days, 12 hours, 30 minutes
    Granularity   this   answer (4): 6 days, 12 hours, 30 minutes and 40 seconds
    Granularity Bolton's answer (4): 6 days, 12 hours, 30 minutes, 40 seconds
    Granularity   this   answer (5): 6 days, 12 hours, 30 minutes and 40 seconds
    Granularity Bolton's answer (5): 6 days, 12 hours, 30 minutes, 40 seconds

Giây: 604780

    Full - function: 6 days, 23 hours, 59 minutes, 40 seconds
    Full -    class: 6 days, 23 hours, 59 minutes and 40 seconds
    Granularity   this   answer (1): 1 week
    Granularity Bolton's answer (1): 6 days
    Granularity   this   answer (2): 1 week
    Granularity Bolton's answer (2): 6 days, 23 hours
    Granularity   this   answer (3): 1 week
    Granularity Bolton's answer (3): 6 days, 23 hours, 59 minutes
    Granularity   this   answer (4): 6 days, 23 hours, 59 minutes and 40 seconds
    Granularity Bolton's answer (4): 6 days, 23 hours, 59 minutes, 40 seconds
    Granularity   this   answer (5): 6 days, 23 hours, 59 minutes and 40 seconds
    Granularity Bolton's answer (5): 6 days, 23 hours, 59 minutes, 40 seconds

Giây: 2419180

    Full - function: 3 weeks, 6 days, 23 hours, 59 minutes, 40 seconds
    Full -    class: 3 weeks, 6 days, 23 hours, 59 minutes and 40 seconds
    Granularity   this   answer (1): 4 weeks
    Granularity Bolton's answer (1): 3 weeks
    Granularity   this   answer (2): 4 weeks
    Granularity Bolton's answer (2): 3 weeks, 6 days
    Granularity   this   answer (3): 4 weeks
    Granularity Bolton's answer (3): 3 weeks, 6 days, 23 hours
    Granularity   this   answer (4): 4 weeks
    Granularity Bolton's answer (4): 3 weeks, 6 days, 23 hours, 59 minutes
    Granularity   this   answer (5): 3 weeks, 6 days, 23 hours, 59 minutes and 40 seconds
    Granularity Bolton's answer (5): 3 weeks, 6 days, 23 hours, 59 minutes, 40 seconds

Giây: 113478160

    Full - function: 187 weeks, 4 days, 9 hours, 42 minutes, 40 seconds
    Full -    class: 187 weeks, 4 days, 9 hours, 42 minutes and 40 seconds
    Granularity   this   answer (1): 188 weeks
    Granularity Bolton's answer (1): 187 weeks
    Granularity   this   answer (2): 187 weeks and 4 days
    Granularity Bolton's answer (2): 187 weeks, 4 days
    Granularity   this   answer (3): 187 weeks, 4 days and 10 hours
    Granularity Bolton's answer (3): 187 weeks, 4 days, 9 hours
    Granularity   this   answer (4): 187 weeks, 4 days, 9 hours and 43 minutes
    Granularity Bolton's answer (4): 187 weeks, 4 days, 9 hours, 42 minutes
    Granularity   this   answer (5): 187 weeks, 4 days, 9 hours, 42 minutes and 40 seconds
    Granularity Bolton's answer (5): 187 weeks, 4 days, 9 hours, 42 minutes, 40 seconds

Tôi đã có một bản dịch tiếng Pháp sẵn sàng.Nhưng thật nhanh khi thực hiện bản dịch ... chỉ vài từ.Hy vọng điều này có thể giúp ích như câu trả lời khác giúp tôi rất nhiều.