Ansible 使用 to_datetime 过滤器并生成 UTC 时间

Ansible use to_datetime filter and produce time in UTC

我需要设置一个变量,它是自该字符串的纪元表示以来的秒数,以 UTC 表示。

start_time: "2021-06-24 22:00:00"

除了控制系统的时间视图,我不能让它产生任何东西,这意味着控制系统的时区而不是 UTC。

- set_fact:
    start_time: "{{ ( start_time  | to_datetime).strftime('%s') }}"

根据 EST,以上仅产生自纪元以来的秒数。

有什么我可以传递给上面的过滤器,所以它会输出 UTC 时间吗?

我已经尝试使用 python's documentation 中提到的方法,但似乎并不是所有的方法都适用于我在 ansible 的 to_datetime.

中可以使用的方法

谢谢。

我不知道是否有仅使用剧本的好方法,但编写自定义过滤器相对容易。例如,如果我将以下代码放入 filter_plugins/timefilters.py(其中 filter_plugins 目录与我的剧本相邻)...

import datetime


def filter_to_utc(v, format='%Y-%m-%d %H:%M:%S'):
    t_local = datetime.datetime.strptime(v, format).astimezone()
    offset = t_local.utcoffset()
    t_utc = (t_local - offset).replace(tzinfo=datetime.timezone.utc)
    return t_utc


class FilterModule:
    def filters(self):
        return {
            'to_utc': filter_to_utc,
        }

...那么我可以编写以下剧本:

- hosts: localhost
  gather_facts: false
  vars:
    start_time: "2021-06-24 22:00:00"
  tasks:
    - set_fact:
        start_time_utc: "{{ start_time | to_utc }}"

    - debug:
        msg: '{{ start_time }} -> {{ start_time_utc }}'

并得到这个输出:


PLAY [localhost] *****************************************************************************

TASK [set_fact] ******************************************************************************
ok: [localhost]

TASK [debug] *********************************************************************************
ok: [localhost] => {
    "msg": "2021-06-24 22:00:00 -> 2021-06-25 02:00:00+00:00"
}

PLAY RECAP ***********************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


更新 我想我更喜欢@mdaniel 的解决方案。仍然要记住,如果您有复杂的逻辑,只需将其放入自定义过滤器插件中就非常简单。

据我所知,您需要对该过滤器使用 (遗憾的是未记录) format= kwarg 来要求它解释 +0000 偏移量,隐式设置结果 datetime 对象的 tz

- set_fact:
    start_time: '2020-12-31 23:59:59'
- debug:
    msg: epoch localtime is {{ (start_time | to_datetime).timestamp() }}
- debug:
    msg: epoch UTC is {{
      ((start_time ~ "+0000") | to_datetime(format="%Y-%m-%d %H:%M:%S%z")).timestamp() }}

产量:

    "msg": "epoch localtime is 1609487999.0"
    "msg": "epoch UTC is 1609459199.0"

当输入 gdate 进行比较时,它似乎表现得很正常:

$ gdate --date @1609487999.0
Thu Dec 31 23:59:59 PST 2020
$ gdate -u --date @1609459199.0
Thu Dec 31 23:59:59 UTC 2020