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
我需要设置一个变量,它是自该字符串的纪元表示以来的秒数,以 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