Python command parameter indicating time delta

Question:

I need to specify a parameter to a python script indicating time back from now. For example 1d is 1 day from now, 2h is 2 hours from now, 2d3h is 2 days, 3 hours from now. Similar to the journalctl --vacuum-time format (reference).

For example, this script will collect the data between now and 2 days and 3 hours in the past:

collect_data_script.py --start=2d3h

Is there some standard way to handle this parameter and a package that can process this time format? Or I will have to write it from scratch?

Asked By: ilya1725

||

Answers:

The ISO 8601 duration format like 2DT3H for "2 days (time designator) 3 hours" can be parsed using module isodate from Gerhard Weiss:

implements ISO 8601 date, time and duration parsing. The implementation follows ISO8601:2004 standard

parse_duration:
parses an ISO 8601 duration string into a timedelta or Duration object.

Example:

import isodate

isodate.parse_duration('p2d3h'.upper())  # prefix with 'p' for period and to uppercase
# will raise ValueError because ISO 8601 time designator 'T' missing

timedelta = isodate.parse_duration('p2dt3h'.upper())  # insert 'T' to work
# datetime.timedelta(2, 10800)
print(timedelta)
# 2 days, 3:00:00

Similar modules

  • arrow: offers a sensible and human-friendly approach to creating, manipulating, formatting and converting dates, times and timestamps.
  • duration: python time duration conversion module
  • iso8601: Simple module to parse ISO 8601 dates

See also:

Answered By: hc_dev

@hc_dev solution will work. However, I used a slightly different one that needed fewer additional modules. Just posting here for reference:

from datetime import datetime, timedelta
from dateutil import parser

def process_cmd_time(time_str, bound) -> datetime:
    """
    Convert passed string to the datetime object.
    Will throw ParseError or ValueError if the string is invalid

    Keyword arguments:
    time_str - string representation of the time to set
    bound - flag to force time bound to 24h from now
    """

    time_str = time_str.strip()
    go_back = time_str[0] == '-'

    # Attempt to get the date. Will throw ParseError if invalid
    input_date = parser.parse(time_str)

    # If the time needs to go back, find the delta from the beginning of today,
    # then subtract from now
    if go_back:
        delta_today = input_date - parser.parse("0h0m0s")
        input_date = datetime.now() - delta_today

    if bound:
        delta_time = datetime.now() - input_date
        if delta_time.days > 0:
            input_date = datetime.now() - timedelta(hours=24, minutes=0, seconds=0)

    return input_date
Answered By: ilya1725