python 'x days ago' to datetime

前端 未结 7 2114
谎友^
谎友^ 2021-01-11 09:35

I have strings that show a date in the following format:

x minutes/hours/days/months/years ago

I need to parse that to a datetime using pyt

7条回答
  •  灰色年华
    2021-01-11 09:55

    completely exaggerated solution but I needed something more flexible:

    def string_to_delta(relative):
        #using simplistic year (no leap months are 30 days long.
        #WARNING: 12 months != 1 year
        unit_mapping = [('mic', 'microseconds', 1),
                        ('millis', 'microseconds', 1000),
                        ('sec', 'seconds', 1),
                        ('day', 'days', 1),
                        ('week', 'days', 7),
                        ('mon', 'days', 30),
                        ('year', 'days', 365)]
        try:
            tokens = relative.lower().split(' ')
            past = False
            if tokens[-1] == 'ago':
                past = True
                tokens =  tokens[:-1]
            elif tokens[0] == 'in':
                tokens = tokens[1:]
    
    
            units = dict(days = 0, seconds = 0, microseconds = 0)
            #we should always get pairs, if not we let this die and throw an exception
            while len(tokens) > 0:
                value = tokens.pop(0)
                if value == 'and':    #just skip this token
                    continue
                else:
                    value = float(value)
    
                unit = tokens.pop(0)
                for match, time_unit, time_constant in unit_mapping:
                    if unit.startswith(match):
                        units[time_unit] += value * time_constant
            return datetime.timedelta(**units), past
    
        except Exception as e:
            raise ValueError("Don't know how to parse %s: %s" % (relative, e))
    

    This can parse things like:

    • 2 days ago
    • in 60 seconds
    • 2 DAY and 4 Secs
    • in 1 year, 1 Month, 2 days and 4 MICRO
    • 2 Weeks 4 secs ago
    • 7 millis ago

    A huge but: It simplifies month and year to 30 and 365 days respectively. Not always what you want, though it's enough for some cases.

提交回复
热议问题