This is not correct (at least for the builtin plugins, and while it would theoretically be possible for other plugins to ignore updates it would break the API expectations and usually be a bad idea.)
The cache affects whether facts that you have not gathered in the current run are available, and (in some configurations) whether play-level gathering happens. Gathered facts are always updated.
- hosts: localhost
gather_facts: false
tasks:
- name: Uses the cached value because facts were not gathered
debug:
msg: "{{ ansible_facts.date_time.time }}"
- gather_facts:
- name: Has the freshly gathered value
debug:
msg: "{{ ansible_facts.date_time.time }}"
- gather_facts:
gather_subset: "!all,!date_time"
- name: Still the fresher value
debug:
msg: "{{ ansible_facts.date_time.time }}"
- gather_facts:
gather_subset: date_time
- name: Refreshed again
debug:
msg: "{{ ansible_facts.date_time.time }}"
PLAY [localhost] ***************************************************************
TASK [Uses the cached value because facts were not gathered] *******************
ok: [localhost] =>
msg: '14:51:14'
TASK [gather_facts] ************************************************************
ok: [localhost]
TASK [Has the freshly gathered value] ******************************************
ok: [localhost] =>
msg: '14:53:41'
TASK [gather_facts] ************************************************************
ok: [localhost]
TASK [Still the fresher value] *************************************************
ok: [localhost] =>
msg: '14:53:41'
TASK [gather_facts] ************************************************************
ok: [localhost]
TASK [Refreshed again] *********************************************************
ok: [localhost] =>
msg: '14:53:43'