This code is very old. I’ve updated it in another post.
for calendar entities…
{%- set word_for_and = 'and' %}
{%- set up_time = (states('calendar.xyz', 'end_time') | as_datetime | as_local - now()).total_seconds() %}
{%- macro phrase(name, plural_name, divisor, mod=None) %}
{%- set value = ((up_time // divisor) % (mod if mod else divisor)) | int %}
{%- set name = plural_name if value > 1 else name %}
{{- '{} {}'.format(value, name) if value | int > 0 else '' }}
{%- endmacro %}
{%- set values = [
phrase('week', 'weeks', 60*60*24*7),
phrase('day', 'days', 60*60*24, 7),
phrase('hour', 'hours', 60*60, 24),
phrase('minute', 'minutes', 60),
phrase('second', 'seconds', 1, 60)
] | select('!=','') | list %}
{{ values[:-1] | join(', ') ~ ' ' ~ word_for_and ~ ' ' ~ values[-1] if values | length > 1 else values | first | default }}