Skip to content

TimeHelpers

psengine.helpers.helpers.TimeHelpers

Helpers for time related functions.

is_rel_time_valid staticmethod

is_rel_time_valid(rel_time: str) -> bool

Helper function to determine if relative time expression is valid.

PARAMETER DESCRIPTION
rel_time

Relative time expression to validate.

TYPE: str

RETURNS DESCRIPTION
bool

True if valid, False otherwise.

Source code in psengine/helpers/helpers.py
@staticmethod
def is_rel_time_valid(
    rel_time: Annotated[str, Doc('Relative time expression to validate.')],
) -> Annotated[bool, Doc('True if valid, False otherwise.')]:
    """Helper function to determine if relative time expression is valid."""
    if rel_time is None or not isinstance(rel_time, str):
        return False

    return bool(re.match(VALID_TIME_REGEX, rel_time))

is_valid_time_range staticmethod

is_valid_time_range(range_: str) -> bool

Verifies if an ISO 8601 compliant time range was specified.

PARAMETER DESCRIPTION
range_

ISO 8601-style time range to validate.

TYPE: str

Example
1
2
3
4
5
    [2017-07-30,2017-07-31]
    (2017-07-30,2017-07-31)
    [2017-07-30,2017-07-31)
    [2017-07-30,)
    [,2017-07-31)

For format reference see: https://www.elastic.co/guide/en/elasticsearch/reference/current/date.html

RETURNS DESCRIPTION
bool

True if valid, False otherwise.

Source code in psengine/helpers/helpers.py
@staticmethod
def is_valid_time_range(
    range_: Annotated[str, Doc('ISO 8601-style time range to validate.')],
) -> Annotated[bool, Doc('True if valid, False otherwise.')]:
    """Verifies if an ISO 8601 compliant time range was specified.

    Example:
        ```python
            [2017-07-30,2017-07-31]
            (2017-07-30,2017-07-31)
            [2017-07-30,2017-07-31)
            [2017-07-30,)
            [,2017-07-31)
        ```
    For format reference see:
        https://www.elastic.co/guide/en/elasticsearch/reference/current/date.html
    """
    if range_ is None:
        return False

    match = re.match(r'^(\[|\()(.*)?,\s*(.*)?(\]|\))$', range_)
    if match is None:
        return False

    start_time, end_time = match.groups()[1], match.groups()[2]
    try:
        if start_time != '' and not TimeHelpers.is_rel_time_valid(start_time):
            date_parse(start_time)
        if end_time != '' and not TimeHelpers.is_rel_time_valid(end_time):
            date_parse(end_time)
    except ValueError:
        return False
    return True

rel_time_to_date staticmethod

rel_time_to_date(
    relative_time: str, start_time: str | None = None
) -> str

Convert a relative time to a date.

relative_time specification: - 1h means 1 hour ago - -1h means 1 hour ago - +1h means 1 hour in the future

PARAMETER DESCRIPTION
relative_time

Relative time string like '7d', '3h', '4m' (minutes).

TYPE: str

start_time

Defined starting time in format %Y-%m-%d %H:%M:%S, if none it will be the run time

TYPE: str | None DEFAULT: None

Example
1
2
3
4
5
rel_time_to_date("1h")  # returns ISO datetime string ~1 hour ago
rel_time_to_date("1d")  # returns ISO datetime string ~1 day ago
rel_time_to_date("+10m")  # returns ISO datetime string 10 minutes in the future
rel_time_to_date("1h", "2022-01-22 22:12:20") # returns 1 hour ago from the specified
rel_time_to_date("+1h", "2022-01-22 22:14:20") # returns 1 hour after from the specified
RAISES DESCRIPTION
ValueError

If relative_time is invalid.

RETURNS DESCRIPTION
str

Formatted date string in ISO format, e.g., '2022-08-08T13:11'.

Source code in psengine/helpers/helpers.py
@staticmethod
def rel_time_to_date(
    relative_time: Annotated[str, Doc("Relative time string like '7d', '3h', '4m' (minutes).")],
    start_time: Annotated[
        str | None,
        Doc(
            'Defined starting time in format %Y-%m-%d %H:%M:%S, if none it will be the run time'
        ),
    ] = None,
) -> Annotated[str, Doc("Formatted date string in ISO format, e.g., '2022-08-08T13:11'.")]:
    """Convert a relative time to a date.

    `relative_time` specification:
        - `1h` means 1 hour ago
        - `-1h` means 1 hour ago
        - `+1h` means 1 hour in the future

    Example:
        ```python
        rel_time_to_date("1h")  # returns ISO datetime string ~1 hour ago
        rel_time_to_date("1d")  # returns ISO datetime string ~1 day ago
        rel_time_to_date("+10m")  # returns ISO datetime string 10 minutes in the future
        rel_time_to_date("1h", "2022-01-22 22:12:20") # returns 1 hour ago from the specified
        rel_time_to_date("+1h", "2022-01-22 22:14:20") # returns 1 hour after from the specified
        ```

    Raises:
        ValueError: If `relative_time` is invalid.
    """
    logger = logging.getLogger(__name__)
    match = re.match(VALID_TIME_REGEX, relative_time)
    if match is None:
        raise ValueError(
            f"Invalid relative time '{relative_time}'. Accepted format: [-|+]?[integer][h|d|m]",
        )
    start_time = (
        datetime.strptime(start_time, TIMESTAMP_STR)
        if start_time
        else datetime.now(timezone.utc)
    )

    sign = match.groups()[0]
    operation = operator.add if sign == '+' else operator.sub

    relative_time = match.groups()[-1]
    digit = int(re.findall(r'^\d+', relative_time)[0])
    if relative_time.endswith('d'):
        result = (operation(start_time, timedelta(days=digit))).strftime('%Y-%m-%dT%H:%M')
    elif relative_time.endswith('h'):
        result = (operation(start_time, timedelta(hours=digit))).strftime('%Y-%m-%dT%H:%M')
    else:
        result = (operation(start_time, timedelta(minutes=digit))).strftime('%Y-%m-%dT%H:%M')

    logger.debug(f'UTC Time now: {start_time}')
    logger.debug(f'Relative time {sign}{relative_time} to date: {result}')

    return result