2

Am using the ansible_date_time.hour and ansible_date_time.minute in one of my playbooks.

But I need to add time on to these facts (or in a variable).. i.e. if ansible_date_time.hour returns 16 - I want to add a couple of hours, or if ansible_date_time.minute returns 40 - I want it to be 50..

Of course there is a ceiling of 23 and 59 for the hours and mins... as I thought about registering a variable from:

- name: Register HH  
  shell: date '+%H'
  register: HP_HH
- debug: msg="{{ HP_HH.stdout | int + 3 }}"

But obviously if my playbook runs at after 21:00 I am out of luck.

Does anyone have a suggestion or workaround?

techraf
  • 64,883
  • 27
  • 193
  • 198
Richard
  • 19
  • 1
  • 1
  • 2
  • Apologies - I am not trying to be vague. I need the fact/variable to return the current time (hours) plus 2 hours OR the current time (minutes) plus 10 minutes. I did look at the filters documentation, but I didn't see anything which would achieve this. Thanks again – Richard May 04 '17 at 00:13
  • Please see my answer here: https://stackoverflow.com/a/45473547/512965 – Willem van Ketwich Aug 03 '17 at 01:57

2 Answers2

6

AFAIK, there is no way to add/subtract time units out of the box in Ansible.

You can convert strings to datetime object with to_datetime filter (Ansible 2.2+).
You can calculate date difference. See this answer.

But if you don't mind using a simple filter plugin, here you go:

Drop this code as ./filter_plugins/add_time.py near your playbook:

import datetime

def add_time(dt, **kwargs):
    return dt + datetime.timedelta(**kwargs)

class FilterModule(object):

    def filters(self):
        return {
            'add_time': add_time
        }

And you can use your own add_time filter as follows:

- hosts: localhost
  gather_facts: yes
  tasks:
    - debug:
        msg: "Current datetime is {{ ansible_date_time.iso8601 }}"
    - debug:
        msg: "Current time +20 mins {{ ansible_date_time.iso8601[:19] | to_datetime(fmt) | add_time(minutes=20) }}"
      vars:
        fmt: "%Y-%m-%dT%H:%M:%S"

add_time has same parameters as timedelta in Python.

Community
  • 1
  • 1
Konstantin Suvorov
  • 65,183
  • 9
  • 162
  • 193
  • Hi Konstantin, Thank you very much for your response.. I think I am getting close.. However I need to split this into two variables.. +%Y-%m-%d and then +%H:%M I did try that but it fails (my Python skills are non existent): – Richard May 05 '17 at 00:46
  • > - debug: > msg: "Current time +25 mins {{ ansible_date_time.iso8601[:19] | > to_datetime(fmt) | add_time(minutes=25) }}" > vars: > fmt: "%H:%M" "the field 'args' has an invalid value , and could not be converted to an dict" Thanks again for your help here :) – Richard May 05 '17 at 00:54
  • Format string for `to_datetime` filter should match argument string. If you want only `%H:%M`, you should cut that part from iso8610, like `ansible_date_time.iso8601[11:16]` – characters from 11th to 16th. – Konstantin Suvorov May 05 '17 at 05:59
  • Hi Konstantin, Thanks again for your response.. I am getting close.. Can you tell me if this only works with ansible_date_time.iso8601? When I run it against ansible_date_time.date it returns "2017-05-08 00:10:00"..i.e. more than just the date - it includes the number of minutes added. ansible_date_time.date returns 1900-01-01 and an obscure time/result. Thanks again for your help sir – Richard May 08 '17 at 16:53
  • Please read [strptime](https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior) documentation to understand how strings are converted to date objects and what each format directive means. – Konstantin Suvorov May 08 '17 at 17:36
  • Thanks for the reply (and your patience!) I *think* I am using the correct format directive... "%Y-%m-%d" = date "%H:%M" = time – Richard May 08 '17 at 18:32
  • Hi Konstantin, Can you tell me - your method of manipulating the time will only work with ansible_date_time.iso8601? Even when I use ansible_date_time.iso8601_basic_short - I get the same formatting results as above. Could I trouble you for an example using iso8601_basic_short or using ansible_date_time.date or ansible_date_time.time sir? Thanks again – Richard May 10 '17 at 20:28
0

I just came across this in my searching and the solution for me (in ansible 2.9) is much easier.

---
- name: test date math playbook
  hosts: localhost

  tasks: 
    - name: today
      debug:
        msg: "today is {{ '%Y-%m-%dT%H:%M:%S'|strftime(ansible_date_time.epoch) }}"

    - name: one year ago
      debug:
        msg: "one-year-ago-today is {{ '%Y-%m-%dT%H:%M:%S'|strftime( (ansible_date_time.epoch|int) - (60*60*24*365)) }}"

By converting to integer, you can do date math inline (with built in filters)