filter: add new time_delta filter

* Calculate datetime string based upon time delta
  provided by user

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
This commit is contained in:
Abhijeet Kasurde 2025-03-03 12:51:34 -08:00
parent 3fd4cdb119
commit eb65421908
4 changed files with 117 additions and 1 deletions

2
.github/BOTMETA.yml vendored
View file

@ -167,6 +167,8 @@ files:
maintainers: resmo
$filters/to_years.yml:
maintainers: resmo
$filters/time_delta.yml:
maintainers: Akasurde
$filters/unicode_normalize.py:
maintainers: Ajpantuso
$filters/version_sort.py:

View file

@ -7,6 +7,9 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import re
from datetime import timedelta, datetime
from ansible.errors import AnsibleFilterError
@ -130,7 +133,33 @@ def to_years(human_time, **kwargs):
return to_time_unit(human_time, 'y', **kwargs)
class FilterModule(object):
def time_delta(date_time, **kwargs):
''' Return datetime after calculating time delta '''
if not isinstance(date_time, str):
raise AnsibleFilterError('time_delta accepts datetime in string format')
date_format = "%Y-%m-%d %H:%M:%S"
if 'date_format' in kwargs:
date_format = kwargs.get('date_format')
delta = {
'days': kwargs.get('days', 0),
'microseconds': kwargs.get('microseconds', 0),
'milliseconds': kwargs.get('milliseconds', 0),
'minutes': kwargs.get('minutes', 0),
'hours': kwargs.get('hours', 0),
'weeks': kwargs.get('weeks', 0),
}
try:
source_date = datetime.strptime(date_time, date_format)
except ValueError:
raise AnsibleFilterError(
f'Failed to parse provided string into datetime format "{date_format}" provided.'
)
return str(source_date + timedelta(**delta))
class FilterModule:
''' Ansible time jinja2 filters '''
def filters(self):
@ -144,6 +173,7 @@ class FilterModule(object):
'to_weeks': to_weeks,
'to_months': to_months,
'to_years': to_years,
'time_delta': time_delta,
}
return filters

View file

@ -0,0 +1,75 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
DOCUMENTATION:
name: time_delta
short_description: Calculate datetime based upon the user given timedelta
version_added: 10.6.0
description:
- Calculate a new date/time by applying a time delta to a given datetime string.
options:
_input:
description:
- The time string to calculate timedelta from.
- The format should match the O(date_format) unless specified otherwise.
type: string
required: true
date_format:
description:
- The format to parse the given input.
- Defaults to "%Y-%m-%d %H:%M:%S".
- You can specify your own format if the datetime string is in a different format.
- See Python 3 datetime format codes for more information.
type: string
days:
type: integer
description:
- The number of days to add or subtract.
- Default is 0.
microseconds:
type: integer
description:
- The number of microseconds to add or subtract.
- Default is 0.
milliseconds:
type: integer
description:
- The number of milliseconds to add or subtract.
- Default is 0.
minutes:
type: integer
description:
- The number of minutes to add or subtract.
- Default is 0.
hours:
type: integer
description:
- The number of hours to add or subtract.
- Default is 0.
weeks:
type: integer
description:
- The number of weeks to add or subtract.
- Default is 0.
author:
- Abhijeet Kasurde (@Akasurde)
EXAMPLES: |
tomorrow: "{{ '2025-03-12 18:00:00' | community.general.time_delta(days=1, date_format='%Y-%m-%d %H:%M:%S') }}"
# => "2025-03-13T18:00:00"
yesterday: "{{ '2025-03-12 18:00:00' | community.general.time_delta(days=-1) }}"
# => "2025-03-11T18:00:00"
a_month_ago: "{{ '2025/03/12' | community.general.time_delta(days=-30, date_format='%Y/%m/%d') }}"
# => "2025-02-10T00:00:00"
RETURN:
_value:
description:
- Date string after applying the delta in ISO 8601 format.
- Raises AnsibleFilterError on failing to parse the datetime string.
type: string

View file

@ -113,3 +113,12 @@
that:
- res is failed
- "'to_time_unit() got unknown keyword arguments' in res.msg"
- name: test time_delta filter
assert:
that:
- "('2025-03-12 18:00:00' | community.general.time_delta(days=-1)) == '2025-03-11 18:00:00'"
- "('2025-03-12 18:00:00' | community.general.time_delta(minutes=-60)) == '2025-03-12 17:00:00'"
- "('2025-03-12 18:00:00' | community.general.time_delta(hours=-1)) == '2025-03-12 17:00:00'"
- "('2025-03-12 18:00:00' | community.general.time_delta(weeks=-1)) == '2025-03-05 18:00:00'"
- "('2025/03/12' | community.general.time_delta(days=-30, date_format='%Y/%m/%d')) == '2025-02-10 00:00:00'"