Skip to content

Commit 9700872

Browse files
committed
filter: add new time_delta filter
* Calculate datetime string based upon time delta provided by user Signed-off-by: Abhijeet Kasurde <[email protected]>
1 parent 3fd4cdb commit 9700872

File tree

3 files changed

+115
-1
lines changed

3 files changed

+115
-1
lines changed

plugins/filter/time.py

+31-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
__metaclass__ = type
88

99
import re
10+
11+
from datetime import timedelta, datetime
12+
1013
from ansible.errors import AnsibleFilterError
1114

1215

@@ -130,7 +133,33 @@ def to_years(human_time, **kwargs):
130133
return to_time_unit(human_time, 'y', **kwargs)
131134

132135

133-
class FilterModule(object):
136+
def time_delta(date_time, **kwargs):
137+
''' Return datetime after calculating time delta '''
138+
if not isinstance(date_time, str):
139+
raise AnsibleFilterError('time_delta accepts datetime in string format')
140+
date_format = "%Y-%m-%d %H:%M:%S"
141+
if 'date_format' in kwargs:
142+
date_format = kwargs.get('date_format')
143+
144+
delta = {
145+
'days': kwargs.get('days', 0),
146+
'microseconds': kwargs.get('microseconds', 0),
147+
'milliseconds': kwargs.get('milliseconds', 0),
148+
'minutes': kwargs.get('minutes', 0),
149+
'hours': kwargs.get('hours', 0),
150+
'weeks': kwargs.get('weeks', 0),
151+
}
152+
try:
153+
source_date = datetime.strptime(date_time, date_format)
154+
except ValueError:
155+
raise AnsibleFilterError(
156+
f'Failed to parse provided string into datetime format "{date_format}" provided.'
157+
)
158+
159+
return str(source_date + timedelta(**delta))
160+
161+
162+
class FilterModule:
134163
''' Ansible time jinja2 filters '''
135164

136165
def filters(self):
@@ -144,6 +173,7 @@ def filters(self):
144173
'to_weeks': to_weeks,
145174
'to_months': to_months,
146175
'to_years': to_years,
176+
'time_delta': time_delta,
147177
}
148178

149179
return filters

plugins/filter/time_delta.yml

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
---
2+
# Copyright: Contributors to the Ansible project
3+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
4+
# SPDX-License-Identifier: GPL-3.0-or-later
5+
6+
DOCUMENTATION:
7+
name: time_delta
8+
short_description: Calculate datetime based upon the user given timedelta
9+
version_added: 10.6.0
10+
description:
11+
- Calculate a new date/time by applying a time delta to a given datetime string.
12+
options:
13+
_input:
14+
description:
15+
- The time string to calculate timedelta from.
16+
- The format should match the O(date_format) unless specified otherwise.
17+
type: string
18+
required: true
19+
date_format:
20+
description:
21+
- The format to parse the given input.
22+
- Defaults to "%Y-%m-%d %H:%M:%S".
23+
- You can specify your own format if the datetime string is in a different format.
24+
- See Python 3 datetime format codes for more information.
25+
type: string
26+
days:
27+
type: integer
28+
description:
29+
- The number of days to add or subtract.
30+
- Default is 0.
31+
microseconds:
32+
type: integer
33+
description:
34+
- The number of microseconds to add or subtract.
35+
- Default is 0.
36+
milliseconds:
37+
type: integer
38+
description:
39+
- The number of milliseconds to add or subtract.
40+
- Default is 0.
41+
minutes:
42+
type: integer
43+
description:
44+
- The number of minutes to add or subtract.
45+
- Default is 0.
46+
hours:
47+
type: integer
48+
description:
49+
- The number of hours to add or subtract.
50+
- Default is 0.
51+
weeks:
52+
type: integer
53+
description:
54+
- The number of weeks to add or subtract.
55+
- Default is 0.
56+
author:
57+
- Abhijeet Kasurde (@Akasurde)
58+
59+
EXAMPLES: |
60+
61+
tomorrow: "{{ '2025-03-12 18:00:00' | community.general.time_delta(days=1, date_format='%Y-%m-%d %H:%M:%S') }}"
62+
# => "2025-03-13T18:00:00"
63+
64+
yesterday: "{{ '2025-03-12 18:00:00' | community.general.time_delta(days=-1) }}"
65+
# => "2025-03-11T18:00:00"
66+
67+
a_month_ago: "{{ '2025/03/12' | community.general.time_delta(days=-30, date_format='%Y/%m/%d') }}"
68+
# => "2025-02-10T00:00:00"
69+
70+
RETURN:
71+
_value:
72+
description:
73+
- Date string after applying the delta in ISO 8601 format.
74+
- Raises AnsibleFilterError on failing to parse the datetime string.
75+
type: string

tests/integration/targets/filter_time/tasks/main.yml

+9
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,12 @@
113113
that:
114114
- res is failed
115115
- "'to_time_unit() got unknown keyword arguments' in res.msg"
116+
117+
- name: test time_delta filter
118+
assert:
119+
that:
120+
- "('2025-03-12 18:00:00' | community.general.time_delta(days=-1)) == '2025-03-11 18:00:00'"
121+
- "('2025-03-12 18:00:00' | community.general.time_delta(minutes=-60)) == '2025-03-12 17:00:00'"
122+
- "('2025-03-12 18:00:00' | community.general.time_delta(hours=-1)) == '2025-03-12 17:00:00'"
123+
- "('2025-03-12 18:00:00' | community.general.time_delta(weeks=-1)) == '2025-03-05 18:00:00'"
124+
- "('2025/03/12' | community.general.time_delta(days=-30, date_format='%Y/%m/%d')) == '2025-02-10 00:00:00'"

0 commit comments

Comments
 (0)