Files
Home-Assistant-Configs/custom_templates/easy_time.jinja
2025-04-29 18:06:31 -04:00

2120 lines
51 KiB
Django/Jinja
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{%- set default_language = 'en' %}
{%- set languages = {
'en':{
'_language': 'English',
'and': 'and',
'in': 'in',
'ago': 'ago',
'now': 'now',
'lose': 'lose',
'gain': 'gain',
'time':{
'format': '12-hr',
'year': [
'yr',
'year',
'years',
],
'week': [
'wk',
'week',
'weeks',
],
'day': [
'd',
'day',
'days',
],
'hour': [
'hr',
'hour',
'hours',
],
'minute': [
'min',
'minute',
'minutes',
],
'second': [
'sec',
'second',
'seconds',
],
},
'delta':{
'today': 'today',
'tomorrow': 'tomorrow',
'yesterday': 'yesterday',
'next': 'next',
'last': 'last',
},
'days':[
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
],
'months':[
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
],
'time_of_hour':{
0: '{hour} o\'clock',
1: 'a minute past {hour}',
15: 'quarter past {hour}',
30: 'half past {hour}',
45: 'quarter to {hour}',
59: 'a minute to {hour}',
'past_hour': '{minute} past {hour}',
'to_hour': '{minute} to {hour}',
},
'time_of_day':{
'midnight': 'midnight',
'noon': 'noon',
},
},
'sk':{
'_language': 'Slovak',
'and': 'a',
'in': 'v',
'ago': 'pred',
'now': 'teraz',
'lose': 'strata',
'gain': 'zosilnenie',
'time':{
'format': '12-hr',
'year': [
'rok',
'rok',
'roky',
],
'week': [
'týž',
'týždeň',
'týždne',
],
'day': [
'd',
'deň',
'dni',
],
'hour': [
'hod',
'hodina',
'hodiny',
],
'minute': [
'min',
'minúta',
'minúty',
],
'second': [
'sek',
'sekunda',
'sekundy',
],
},
'delta':{
'today': 'dnes',
'tomorrow': 'zajtra',
'yesterday': 'včera',
'next': 'ďalší',
'last': 'predchádzajúci',
},
'days':[
"Pondelok",
"Utorok",
"Streda",
"Štvrtok",
"Piatok",
"Sobota",
"Nedeľa",
],
'months':[
'Január',
'Február',
'Marec',
'Apríl',
'Máj',
'Jún',
'Júl',
'August',
'September',
'Október',
'November',
'December',
]
},
'nl':{
'_language': 'Nederlands',
'and': 'en',
'in': 'over',
'ago': 'geleden',
'now': 'nu',
'lose': 'verliezen',
'gain': 'krijgen',
'time':{
'format': '24-hr',
'year': [
'jr',
'jaar',
'jaar',
],
'week': [
'wk',
'week',
'weken',
],
'day': [
'd',
'dag',
'dagen',
],
'hour': [
'u',
'uur',
'uur',
],
'minute': [
'min',
'minuut',
'minuten',
],
'second': [
'sec',
'seconde',
'seconden',
],
},
'delta':{
'today': 'vandaag',
'tomorrow': 'morgen',
'yesterday': 'gisteren',
'next': 'volgende',
'last': 'afgelopen',
},
'days':[
"maandag",
"dinsdag",
"woensdag",
"donderdag",
"vrijdag",
"zaterdag",
"zondag",
],
'months':[
'januari',
'februari',
'maart',
'april',
'mei',
'juni',
'juli',
'augustus',
'september',
'oktober',
'november',
'december',
],
'time_of_hour':{
0: '{hour} uur',
1: '1 over {hour}',
15: 'kwart over {hour}',
30: 'half {hour}',
45: 'kwart voor {hour}',
59: '1 voor {hour}',
'past_hour': '{minute} over {hour}',
'to_hour': '{minute} voor {hour}',
'to_half_hour': '{minute} voor half {hour}',
'past_half_hour': '{minute} over half {hour}',
'half_hour': 'half {hour}',
'use_twelve': true,
},
'time_of_day':{
'midnight': 'middernacht',
'noon': 'middag',
},
},
'sv':{
'_language': 'Svenska',
'and': 'och',
'in': 'om',
'ago': 'sedan',
'now': 'nu',
'lose': 'förlora',
'gain': 'få',
'time':{
'format': '24-hr',
'year': [
'Å',
'år',
'år',
],
'week': [
'v',
'vecka',
'veckor',
],
'day': [
'd',
'dag',
'dagar',
],
'hour': [
't',
'timme',
'timmar',
],
'minute': [
'min',
'minut',
'minuter',
],
'second': [
'sek',
'sekund',
'sekunder',
],
},
'delta':{
'today': 'idag',
'tomorrow': 'imorgon',
'yesterday': 'igår',
'next': 'nästa',
},
'days':[
"måndag",
"tisdag",
"onsdag",
"torsdag",
"fredag",
"lördag",
"söndag",
],
'months':[
'januari',
'februari',
'mars',
'april',
'maj',
'juni',
'juli',
'augusti',
'september',
'oktober',
'november',
'december',
]
},
'de':{
'_language': 'Deutsch',
'and': 'und',
'in': 'in',
'ago': 'vor %s',
'now': 'jetzt',
'lose': 'Du verlierst',
'gain': 'Du gewinnst',
'time':{
'format': '24-hr',
'year': [
'J',
'Jahr',
'Jahren',
],
'week': [
'W',
'Woche',
'Wochen',
],
'day': [
'T',
'Tag',
'Tagen',
],
'hour': [
'h',
'Stunde',
'Stunden',
],
'minute': [
'm',
'Minute',
'Minuten',
],
'second': [
's',
'Sekunde',
'Sekunden',
],
},
'delta':{
'today': 'Heute',
'tomorrow': 'Morgen',
'yesterday': 'Gestern',
},
'days':[
"Montag",
"Dienstag",
"Mittwoch",
"Donnerstag",
"Freitag",
"Samstag",
"Sonntag",
],
'months':[
'Januar',
'Februar',
'März',
'April',
'Mai',
'Juni',
'Juli',
'August',
'September',
'Oktober',
'November',
'Dezember',
]
},
'da':{
'_language': 'Dansk',
'and': 'og',
'in': 'om',
'ago': 'siden',
'now': 'nu',
'lose': 'mister',
'gain': 'tilføjer',
'time':{
'format': '24-hr',
'year': [
'Å',
'år',
'år',
],
'week': [
'u',
'uge',
'uger',
],
'day': [
'd',
'dag',
'dage',
],
'hour': [
't',
'time',
'timer',
],
'minute': [
'min',
'minut',
'minutter',
],
'second': [
'sek',
'sekund',
'sekunder',
],
},
'delta':{
'today': 'i dag',
'tomorrow': 'i morgen',
'yesterday': 'i går',
},
'days':[
"mandag",
"tirsdag",
"onsdag",
"torsdag",
"fredag",
"lørdag",
"søndag",
],
'months':[
'januar',
'februar',
'marts',
'april',
'maj',
'juni',
'juli',
'august',
'september',
'oktober',
'november',
'december',
]
},
'nb':{
'_language': 'Norsk (Bokmål)',
'and': 'og',
'in': 'om',
'ago': 'siden',
'now': 'nå',
'lose': 'mister',
'gain': 'får',
'time':{
'format': '24-hr',
'year': [
'å',
'år',
'år',
],
'week': [
'u',
'uke',
'uker',
],
'day': [
'd',
'dag',
'dager',
],
'hour': [
't',
'time',
'timer',
],
'minute': [
'min',
'minutt',
'minutter',
],
'second': [
'sek',
'sekund',
'sekunder',
],
},
'delta':{
'today': 'i dag',
'tomorrow': 'i morgen',
'yesterday': 'i går',
},
'days':[
"mandag",
"tirsdag",
"onsdag",
"torsdag",
"fredag",
"lørdag",
"søndag",
],
'months':[
'januar',
'februar',
'mars',
'april',
'mai',
'juni',
'juli',
'august',
'september',
'oktober',
'november',
'desember',
]
},
'nn':{
'_language': 'Norsk (Nynorsk)',
'and': 'og',
'in': 'om',
'ago': 'sia',
'now': 'nå',
'lose': 'mister',
'gain': 'får',
'time':{
'format': '24-hr',
'year': [
'å',
'år',
'år',
],
'week': [
'v',
'veke',
'veker',
],
'day': [
'd',
'dag',
'dagar',
],
'hour': [
't',
'time',
'timar',
],
'minute': [
'min',
'minutt',
'minutt',
],
'second': [
'sek',
'sekund',
'sekund',
],
},
'delta':{
'today': 'i dag',
'tomorrow': 'i morgon',
'yesterday': 'i går',
},
'days':[
"måndag",
"tysdag",
"onsdag",
"torsdag",
"fredag",
"laurdag",
"søndag",
],
'months':[
'januar',
'februar',
'mars',
'april',
'mai',
'juni',
'juli',
'august',
'september',
'oktober',
'november',
'desember',
]
},
'fr':{
'_language': 'Français',
'and': 'et',
'in': 'dans',
'ago': 'il y a %s',
'now': 'maintenant',
'lose': 'perdre',
'gain': 'gagner',
'time':{
'format': '24-hr',
'year': [
'an',
'an',
'ans',
],
'week': [
'sem.',
'semaine',
'semaines',
],
'day': [
'j',
'jour',
'jours',
],
'hour': [
'h',
'heure',
'heures',
],
'minute': [
'min',
'minute',
'minutes',
],
'second': [
's',
'seconde',
'secondes',
],
},
'delta':{
'today': "aujourd'hui",
'tomorrow': 'demain',
'yesterday': 'hier',
'next': 'prochain',
'last': 'dernier',
},
'days':[
"lundi",
"mardi",
"mercredi",
"jeudi",
"vendredi",
"samedi",
"dimanche",
],
'months':[
'janvier',
'février',
'mars',
'avril',
'mai',
'juin',
'juillet',
'août',
'septembre',
'octobre',
'novembre',
'décembre',
]
},
'es':{
'_language': 'Español',
'and': 'y',
'in': 'en',
'ago': 'hace',
'now': 'ahora',
'lose': 'perder',
'gain': 'ganar',
'time':{
'format': '24-hr',
'year': [
'a',
'año',
'años',
],
'week': [
'sem.',
'semana',
'semanas',
],
'day': [
'd',
'día',
'días',
],
'hour': [
'h',
'hora',
'horas',
],
'minute': [
'm',
'minuto',
'minutos',
],
'second': [
's',
'segundo',
'segundos',
],
},
'delta':{
'today': 'hoy',
'tomorrow': 'mañana',
'yesterday': 'ayer',
'next': 'el próximo',
'last': 'el pasado',
},
'days':[
'lunes',
'martes',
'miércoles',
'jueves',
'viernes',
'sábado',
'domingo'
],
'months':[
'enero',
'febrero',
'marzo',
'abril',
'mayo',
'junio',
'julio',
'agosto',
'septiembre',
'octubre',
'noviembre',
'diciembre'
],
'time_of_hour':{
0: '{hour} en punto',
1: '{hour} y un minuto',
15: '{hour} y quarto',
30: '{hour} y media',
45: '{hour} menos quarto',
59: '{hour} menos uno',
'past_hour': '{hour} y {minute}',
'to_hour': '{hour} menos {minute}',
},
'time_of_day':{
'midnight': 'medianoche',
'noon': 'mediodía',
},
},
'it':{
'_language': 'Italiano',
'and': 'e',
'in': 'in',
'ago': 'fa',
'now': 'ora',
'lose': 'perdita',
'gain': 'guadagno',
'time':{
'format': '24-hr',
'year': [
'a.',
'anno',
'anni',
],
'week': [
'set.',
'settimana',
'settimane',
],
'day': [
'g',
'giorno',
'giorni',
],
'hour': [
'h',
'ora',
'ore',
],
'minute': [
'min',
'minuto',
'minuti',
],
'second': [
's',
'secondo',
'secondi',
],
},
'delta':{
'today': 'oggi',
'tomorrow': 'domani',
'yesterday': 'ieri',
},
'days':[
"lunedì",
"martedì",
"mercoledì",
"giovedì",
"venerdì",
"sabato",
"domenica",
],
'months':[
'gennaio',
'febbraio',
'marzo',
'aprile',
'maggio',
'giugno',
'luglio',
'agosto',
'settembre',
'ottobre',
'novembre',
'dicembre',
]
},
'pt':{
'_language': 'Português',
'and': 'e',
'in': 'em',
'ago': 'antes',
'now': 'agora',
'lose': 'perde',
'gain': 'ganha',
'time':{
'format': '24-hr',
'year': [
'aa',
'ano',
'anos',
],
'week': [
'sem',
'semana',
'semanas',
],
'day': [
'd',
'dia',
'dias',
],
'hour': [
'h',
'hora',
'horas',
],
'minute': [
'min',
'minuto',
'minutos',
],
'second': [
'seg',
'segundo',
'segundos',
],
},
'delta':{
'today': 'hoje',
'tomorrow': 'amanhã',
'yesterday': 'ontem',
'next': 'seguinte',
'last': 'anterior',
},
'days':[
"Segunda",
"Terça",
"Quarta",
"Quinta",
"Sexta",
"Sábado",
"Domingo",
],
'months':[
'Janeiro',
'Fevereiro',
'Março',
'Abril',
'Maio',
'Junho',
'Julho',
'Agosto',
'Setembro',
'Outubro',
'Novembro',
'Dezembro',
]
},
'hr':{
'_language': 'Hrvatski',
'and': 'i',
'in': 'u',
'ago': 'prije',
'now': 'sada',
'lose': 'gubiš',
'gain': 'dobivaš',
'time':{
'format': '24-hr',
'year': [
'g',
'godina',
'godine',
],
'week': [
'tj',
'tjedan',
'tjedana',
],
'day': [
'd',
'dan',
'dana',
],
'hour': [
'h',
'sat',
'sati',
],
'minute': [
'm',
'minuta',
'minuta',
],
'second': [
's',
'sekunda',
'sekundi',
],
},
'delta':{
'today': 'danas',
'tomorrow': 'sutra',
'yesterday': 'jučer',
'next': 'sljedeći',
'last': 'protekli',
},
'days':[
"Ponedjeljak",
"Utorak",
"Srijeda",
"Četvrtak",
"Petak",
"Subota",
"Nedjelja",
],
'months':[
'Siječanj',
'Veljača',
'Ožujak',
'Travanj',
'Svibanj',
'Lipanj',
'Srpanj',
'Kolovoz',
'Rujan',
'Listopad',
'Studeni',
'Prosinac',
]
},
'pl':{
'_language': 'Polski',
'and': 'i',
'in': 'w',
'ago': 'temu',
'now': 'teraz',
'lose': 'straciłeś',
'gain': 'zyskałeś',
'time':{
'format': '24-godz',
'year': [
'r',
'rok',
'lata',
],
'week': [
'tyg',
'tydzień',
'tygodnie',
],
'day': [
'd',
'dzień',
'dni',
],
'hour': [
'godz',
'godzina',
'godziny',
],
'minute': [
'min',
'minuta',
'minuty',
],
'second': [
's',
'sekunda',
'sekundy',
],
},
'delta':{
'today': 'dzisiaj',
'tomorrow': 'jutro',
'yesterday': 'wczoraj',
'next': 'następny',
'last': 'poprzedni',
},
'days':[
"Poniedziałek",
"Wtorek",
"Środa",
"Czwartek",
"Piątek",
"Sobota",
"Niedziela",
],
'months':[
'Styczeń',
'Luty',
'Marzec',
'Kwiecień',
'Maj',
'Czerwiec',
'Lipiec',
'Sierpień',
'Wrzesień',
'Październik',
'Listopad',
'Grudzień',
]
},
'ru':{
'_language': 'Русский',
'and': 'и',
'in': 'в',
'ago': 'назад',
'now': 'сейчас',
'lose': 'уменьшение',
'gain': 'увеличение',
'time':{
'format': '24-hr',
'year': [
'г',
'год',
'лет',
],
'week': [
'нед',
'неделя',
'недель',
],
'day': [
'д',
'день',
'дней',
],
'hour': [
'ч',
'час',
'часов',
],
'minute': [
'мин',
'минута',
'минут',
],
'second': [
'сек',
'секунда',
'секунд',
],
},
'delta':{
'today': 'сегодня',
'tomorrow': 'завтра',
'yesterday': 'вчера',
'next': 'следующий',
'last': 'последний',
},
'days':[
"Понедельник",
"Вторник",
"Среда",
"Четверг",
"Пятница",
"Суббота",
"Воскресенье",
],
'months':[
'Январь',
'Февраль',
'Март',
'Апрель',
'Май',
'Июнь',
'Июль',
'Август',
'Сентябрь',
'Октябрь',
'Ноябрь',
'Декабрь',
],
'time_of_hour':{
0: '{hour} часов ровно',
1: '{hour} и 1 минута',
15: '{hour} с четвертью',
30: '{hour} с половиной',
45: 'без четверти {hour}',
59: 'без минуты {hour}',
'past_hour': '{hour} и {minute} минут',
'to_hour': 'без {minute} минут {hour}',
},
'time_of_day':{
'midnight': 'полночь',
'noon': 'полдень',
},
},
'uk':{
'_language': 'Українська',
'and': 'і',
'in': 'в',
'ago': 'тому',
'now': 'зараз',
'lose': 'зменшення',
'gain': 'збільшення',
'time':{
'format': '24-hr',
'year': [
'р',
'рік',
'роки',
],
'week': [
'тиж',
'тиждень',
'тижні',
],
'day': [
'д',
'день',
'дні',
],
'hour': [
'год',
'година',
'години',
],
'minute': [
'хв',
'хвилина',
'хвилини',
],
'second': [
'сек',
'секунда',
'секунди',
],
},
'delta':{
'today': 'сьогодні',
'tomorrow': 'завтра',
'yesterday': 'вчора',
'next': 'наступний',
'last': 'останній',
},
'days':[
"Понеділок",
"Вівторок",
"Середа",
"Четвер",
"П'ятниця",
"Субота",
"Неділя",
],
'months':[
'Січень',
'Лютий',
'Березень',
'Квітень',
'Травень',
'Червень',
'Липень',
'Серпень',
'Вересень',
'Жовтень',
'Листопад',
'Грудень',
],
'time_of_hour':{
0: '{hour} годин',
1: '{hour} годин(а) одна хвилина',
15: 'чверть на {hour}',
30: 'пів на {hour}',
45: 'за чверть {hour}',
59: 'за хвилину {hour}',
'past_hour': '{hour} та {minute} хвилин',
'to_hour': 'за {minute} хвилин {hour}',
},
'time_of_day':{
'midnight': 'опівночі',
'noon': 'опівдні',
},
},
'zh-Hans':{
'_language': '简体中文',
'and': '',
'in': '',
'ago': '之前',
'now': '现在',
'lose': '失去',
'gain': '获得',
'time':{
'format': '24-hr',
'year': [
'年',
'年',
'年',
],
'week': [
'周',
'星期',
'星期',
],
'day': [
'天',
'天',
'天',
],
'hour': [
'时',
'小时',
'小时',
],
'minute': [
'分',
'分钟',
'分钟',
],
'second': [
'秒',
'秒',
'秒',
],
},
'delta':{
'today': '今天',
'tomorrow': '明天',
'yesterday': '昨天',
'next': '下一个',
'last': '上一个',
},
'days':[
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
"星期日",
],
'months':[
'一月',
'二月',
'三月',
'四月',
'五月',
'六月',
'七月',
'八月',
'九月',
'十月',
'十一月',
'十二月',
],
'time_of_day':{
'midnight': '午夜',
'noon': '正午',
},
},
'ko':{
'_language':'Korean',
'and':'',
'in':'후',
'ago':'전',
'now':'지금',
'lose':'감소',
'gain':'증가',
'time':{
'format':'24-hr',
'year':[
'년',
'년',
'년',
],
'week':[
'주',
'주',
'주',
],
'day':[
'일',
'일',
'일',
],
'hour':[
'시',
'시간',
'시간',
],
'minute':[
'분',
'분',
'분',
],
'second':[
'초',
'초',
'초',
],
},
'delta':{
'today':'오늘',
'tomorrow':'내일',
'yesterday':'어제',
'next':'다음',
'last':'지난',
},
'days':[
'월요일',
'화요일',
'수요일',
'목요일',
'금요일',
'토요일',
'일요일',
],
'months':[
'1월',
'2월',
'3월',
'4월',
'5월',
'6월',
'7월',
'8월',
'9월',
'10월',
'11월',
'12월',
],
'time_of_day':{
'midnight':'자정',
'noon':'정오',
},
},
'cs': {
'_language': 'Čeština',
'and': 'a',
'in': 'za',
'ago': 'před %s',
'now': 'nyní',
'lose': 'ztratit',
'gain': 'získat',
'time': {
'format': '12-hodin',
'year': [
'rok',
'rok',
'roky'
],
'week': [
'týd',
'týden',
'týdny'
],
'day': [
'd',
'den',
'dny'
],
'hour': [
'hod',
'hodina',
'hodiny'
],
'minute': [
'min',
'minuta',
'minuty'
],
'second': [
'sek',
'sekunda',
'sekundy'
]
},
'delta': {
'today': 'dnes',
'tomorrow': 'zítra',
'yesterday': 'včera',
'next': 'příští',
'last': 'poslední'
},
'days': [
'Pondělí',
'Úterý',
'Středa',
'Čtvrtek',
'Pátek',
'Sobota',
'Neděle'
],
'months': [
'Leden',
'Únor',
'Březen',
'Duben',
'Květen',
'Červen',
'Červenec',
'Srpen',
'Září',
'Říjen',
'Listopad',
'Prosinec'
],
'time_of_hour': {
0: '{hour} hodin',
1: 'minuta po {hour}',
15: 'čtvrt na {hour}',
30: 'půl {hour}',
45: 'tři čtvrtě na {hour}',
59: 'minuta do {hour}',
'past_hour': '{minute} po {hour}',
'to_hour': '{minute} do {hour}'
},
'time_of_day': {
'midnight': 'půlnoc',
'noon': 'poledne'
}
}
} %}
{# DO NOT MODIFY BELOW THIS LINE #}
{% set valid_entity_id_pattern = '^(?!.+__)(?!_)[\\da-z_]+(?<!_)\\.(?!_)[\\da-z_]+(?<!_)$' %}
{% set _bad_value = '?' %}
{% set _durations = {
'year': 31536000,
'week': 604800,
'day': 86400,
'hour': 3600,
'minute': 60,
'second': 1,
} %}
{% set _periods = {
'week': 52,
'day': 7,
'hour': 24,
'minute': 60,
'second': 60,
} %}
{%- set _duration_sensor = {
'd': 86400,
'h': 3600,
'min': 60,
's': 1,
} %}
{% set _time_formats = {
'12-hr': '%-I:%M %p',
'24-hr': '%H:%M',
} %}
{% set _default_time_format = _time_formats.get('24-hr') %}
{% set _default_values = _durations.keys() | list %}
{%- macro _catchup(n) %}
{%- for i in range(n) %}
-
{%- endfor %}
{%- endmacro %}
{%- macro translate(k1, k2=None, k3=None, k4=None, k5=None, index=None, fallback=None, language=None) %}
{#- This macro is ugly, but fast, don't change it #}
{%- set l = language or default_language %}
{%- set dflt = _bad_value if fallback is none else fallback %}
{%- if k2 is not none and k3 is not none and k4 is not none and k5 is not none %}
{%- set output = languages.get(l, {}).get(k1, {}).get(k2, {}).get(k3, {}).get(k4, {}).get(k5) %}
{%- elif k2 is not none and k3 is not none and k4 is not none and k5 is none %}
{%- set output = languages.get(l, {}).get(k1, {}).get(k2, {}).get(k3, {}).get(k4) %}
{%- elif k2 is not none and k3 is not none and k4 is none and k5 is none %}
{%- set output = languages.get(l, {}).get(k1, {}).get(k2, {}).get(k3) %}
{%- elif k2 is not none and k3 is none and k4 is none and k5 is none %}
{%- set output = languages.get(l, {}).get(k1, {}).get(k2) %}
{%- else %}
{%- set output = languages.get(l, {}).get(k1) %}
{%- endif %}
{%- if output is none %}
{{- dflt }}
{%- elif index is not none and index is integer and output is list %}
{{- output[index] }}
{%- else %}
{{- output}}
{%- endif %}
{%- endmacro %}
{%- macro _get_language_time_format(override, language) %}
{%- set lang_fmat = translate('time', 'format', language=language) %}
{%- set fmat = _time_formats.get(override, _default_time_format) if override in _time_formats.keys() else _time_formats.get(lang_fmat, _default_time_format) %}
{{- fmat }}
{%- endmacro %}
{%- macro _delta_seconds(a, b) %}
{{- (b - a).total_seconds() | round(0) }}
{%- endmacro %}
{#- this function isn't needed, I only created it to keep the 'delta' consistent with _delta_seconds #}
{%- macro _delta_timedelta(a, b) %}
{{- b - a }}
{%- endmacro %}
{%- macro _to_utc(dt) -%}
{%- set time = now() -%}
{%- set offset = time.utcoffset() - time.dst() if time.dst() else time.utcoffset() -%}
{{- dt.astimezone(utcnow().tzinfo) + offset -}}
{%- endmacro -%}
{%- macro _check_for_duration_sensor(input) %}
{%- if input is string and input | regex_search(valid_entity_id_pattern) and input.startswith('sensor') and states[input] is not none and states[input].attributes.device_class is defined and states[input].attributes.unit_of_measurement is defined -%}
{%- set obj = states[input] -%}
{%- set multiplier = _duration_sensor.get(obj.attributes.unit_of_measurement) -%}
{{- (obj.state | float * multiplier) | string | as_timedelta -}}
{%- else %}
{{- '' -}}
{%- endif -%}
{%- endmacro -%}
{%- macro _to_datetime(input, attribute=None, utc=False) -%}
{#- Already a datetime -#}
{%- if input is datetime -%}
{%- if input.tzinfo is none and utc -%}
{{- _toutc(input) -}}
{%- elif input.tzinfo is none -%}
{{- input | as_local -}}
{%- else -%}
{{- input -}}
{%- endif -%}
{#- assume time in seconds -#}
{%- elif input is integer or input is float -%}
{{- input | as_datetime -}}
{#- assume time as string or entity_id -#}
{%- elif input is string and input not in ['', 'None'] -%}
{#- if entity_id -#}
{%- if input | regex_search(valid_entity_id_pattern) -%}
{%- if attribute is not none and attribute is string -%}
{{- _to_datetime(state_attr(input, attribute), None) -}}
{%- elif input.startswith('input_datetime') and is_state_attr(input, 'has_date', False) -%}
{{- today_at(states(input)) }}
{%- elif input.startswith('calendar') and attribute is none %}
{{- _to_datetime(state_attr(input, 'start_time'), None) -}}
{%- else %}
{{- _to_datetime(states(input), None) -}}
{%- endif %}
{%- else -%}
{#- Test datetime as a string -#}
{%- set _is_datetime = input | as_datetime -%}
{%- if _is_datetime -%}
{%- if input | regex_search('(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])$') -%}
{#- TZ Aware -#}
{{- _is_datetime -}}
{%- elif utc -%}
{#- UTC -#}
{{- (input ~ '+00:00') | as_datetime }}
{%- else -%}
{#- Local -#}
{{- _is_datetime | as_local -}}
{%- endif -%}
{%- else -%}
{{- None -}}
{%- endif -%}
{%- endif -%}
{%- else -%}
{{- None -}}
{%- endif -%}
{%- endmacro -%}
{%- macro _get_period_value(id, uptime_seconds) %}
{%- set duration = _durations.get(id, 1) %}
{%- set period = _periods.get(id) %}
{{- ((uptime_seconds // duration) % (period if period else duration)) | int }}
{%- endmacro %}
{%- macro _get_period_max(id, uptime_seconds) %}
{%- set duration = _durations.get(id, 1) %}
{{- uptime_seconds // duration }}
{%- endmacro %}
{%- macro _get_period_round(id, uptime_seconds) %}
{%- set duration = _durations.get(id, 1) %}
{{- (uptime_seconds / duration) | round }}
{%- endmacro %}
{# macro to generate a time #}
{%- macro _phrase(id, uptime_seconds, language, max, raw, round_value=False) %}
{%- if round_value %}
{%- set func = _get_period_round %}
{%- else %}
{%- set func = _get_period_max if max else _get_period_value %}
{%- endif %}
{%- set value = func(id, uptime_seconds) | int %}
{%- set name = translate('time', id, index=2, language=language) if value != 1 else translate('time', id, index=1, language=language) %}
{{- '{} {}'.format(value, name) if value | int > 0 or raw else '' -}}
{% endmacro %}
{%- macro _time_dict(uptime_seconds) %}
{%- set ns = namespace(ret=[]) %}
{%- for item in _default_values %}
{%- set ns.ret = ns.ret + [(item, _get_period_value(item, uptime_seconds) | int)] %}
{%- endfor %}
{{- dict.from_keys(ns.ret) | to_json }}
{%- endmacro %}
{# macro to generate a friendly phrase #}
{%- macro _just_time(seconds, language, values, biggest, raw=False, short=False, floor=False) %}
{%- if seconds < 1 %}
{{- translate('now', language=language) }}
{%- else %}
{#- this used to be a macro, was slow because it converted to/from json #}
{%- set ns = namespace(ret=[]) %}
{#- ensure we have a list of values #}
{%- set values = [ values ] if values is string else values %}
{#- filter values to only have items in _default_values #}
{%- set values = values | select('in', _default_values) | list %}
{#- this should be a good list of values if the previous 2 filters didn't remove anything #}
{%- set values = _default_values | select('in', values) | list if values else _default_values %}
{%- set index = values.index(values | first | default) %}
{%- for item in values[index:] %}
{%- set duration = _durations.get(item, 1) %}
{%- set period = _periods.get(item, 0) %}
{%- set value = ((seconds // duration) % (period if period else duration)) | int %}
{%- if value > 0 or raw %}
{%- if ns.ret | length == 0 %}
{%- set chosen = (seconds / duration) | round if biggest and not floor else seconds // duration %}
{%- else %}
{%- set chosen = value %}
{%- endif %}
{%- set chosen = chosen | int %}
{%- if short %}
{%- set units = translate('time', item, index=0, language=language) %}
{%- else %}
{%- set units = translate('time', item, index=2, language=language) if chosen != 1 else translate('time', item, index=1, language=language) %}
{%- set units = ' %s' % units %}
{%- endif %}
{%- set ns.ret = ns.ret + [ '%s%s' % (chosen, units) ] %}
{%- if biggest and ns.ret | length == 1 %}
{%- break %}
{%- endif %}
{%- endif %}
{%- endfor %}
{%- set phrases = ns.ret %}
{#- add our langauges to the phrases #}
{%- if phrases | length > 0 %}
{%- set word_for_and = ' ' if short else ' %s ' % translate('and', language=language) %}
{{- phrases[:-1] | join(', ') ~ word_for_and ~ phrases[-1] if phrases | length > 1 else phrases | first | default }}
{%- else %}
{{- _just_time(seconds, language, values, biggest, True, short, floor) }}
{%- endif %}
{%- endif %}
{%- endmacro %}
{# macro to generate a friendly time phrase #}
{%- macro _time(input, attribute, language, values, biggest, utc, short=False, floor=False) %}
{%- set duration_sensor = _check_for_duration_sensor(input) %}
{%- if duration_sensor %}
{%- set seconds = as_timedelta(duration_sensor).total_seconds() %}
{{- _just_time(seconds, language, values, biggest, short=short, floor=floor) }}
{%- else %}
{%- set uptime = _to_datetime(input, attribute, utc) | as_datetime %}
{%- if uptime %}
{%- set value = _delta_seconds(now(), uptime) | int %}
{%- set seconds = value | abs %}
{{- _just_time(seconds, language, values, biggest, short=short, floor=floor) }}
{%- else %}
{{- _bad_value }}
{%- endif %}
{%- endif %}
{%- endmacro %}
{%- macro _time_between(func, input1, attr1, utc1, input2, attr2, utc2) -%}
{%- set t1 = _to_datetime(input1, attr1, utc1) | as_datetime | as_local -%}
{%- set t2 = _to_datetime(input2, attr2, utc2) | as_datetime | as_local -%}
{%- if t1 is not none and t2 is not none -%}
{{- func(t1, t2) -}}
{%- else -%}
{{- None -}}
{%- endif -%}
{%- endmacro -%}
{# Returns the most significant time. e.g. 3 hours #}
{%- macro easy_time(uptime, attribute=None, language=default_language, utc=False, max_period='year', short=False, floor=False) %}
{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %}
{{- _time(uptime, attribute, language, values, True, utc, short, floor) }}
{%- endmacro %}
{# Returns a large time phrase without missing any detail. e.g. 3 hours, 4 minutes and 1 second #}
{%- macro big_time(uptime, attribute=None, language=default_language, utc=False, max_period='year', short=False) %}
{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %}
{{- _time(uptime, attribute, language, values, False, utc, short) }}
{%- endmacro %}
{# Returns a time phrase with only the details you care about most of the time. e.g. 3 hours and 4 minutes #}
{%- macro custom_time(uptime, values='', language=default_language, utc=False, short=False) %}
{%- set args = values.replace(' ','').split(',') | list if values is string else [] %}
{%- if args %}
{{- _time(uptime, None, language, args, False, utc, short) }}
{%- else %}
{{- _time(uptime, attribute, language, _default_values, False, utc, short) }}
{%- endif %}
{%- endmacro %}
{%- macro custom_time_attr(uptime, attribute, values='', language=default_language, utc=False, short=False) %}
{%- set args = values.replace(' ','').split(',') | list if values is string else [] %}
{%- if args %}
{{- _time(uptime, attribute, language, args, False, utc, short) }}
{%- else %}
{{- _time(uptime, attribute, language, _default_values, False, utc, short) }}
{%- endif %}
{%- endmacro %}
{%- macro easy_time_between(t1, t2, attr1=None, attr2=None, language=default_language, utc1=False, utc2=False, max_period='year', short=False, floor=False) %}
{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %}
{%- set seconds = _time_between(_delta_seconds, t1, attr1, utc1, t2, attr2, utc2) | float | abs %}
{{- _just_time(seconds, language, values, True, short=short, floor=floor) }}
{%- endmacro %}
{%- macro big_time_between(t1, t2, attr1=None, attr2=None, language=default_language, utc1=False, utc2=False, max_period='year', short=False) %}
{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %}
{%- set seconds = _time_between(_delta_seconds, t1, attr1, utc1, t2, attr2, utc2) | float | abs %}
{{- _just_time(seconds, language, values, False, short=short) }}
{%- endmacro %}
{%- macro custom_time_between(t1, t2, values='', attr1=None, attr2=None, language=default_language, utc1=False, utc2=False, max_period='year', short=False) %}
{%- set values = values.replace(' ','').split(',') | list if values is string else [] %}
{%- set seconds = _time_between(_delta_seconds, t1, attr1, utc1, t2, attr2, utc2) | float | abs %}
{{- _just_time(seconds, language, values, False, short=short) }}
{%- endmacro %}
{%- macro time_between(t1, t2, attr1=None, attr2=None, utc1=False, utc2=False) %}
{{- _time_between(_delta_timedelta, t1, attr1, utc1, t2, attr2, utc2) }}
{%- endmacro %}
{# macro to generate a friendly relative time phrase #}
{%- macro _relative_time(input, attribute, language, values, biggest, utc, short=False, floor=False) %}
{%- set uptime = _to_datetime(input, attribute, utc) | as_datetime %}
{%- if uptime %}
{%- set value = _delta_seconds(now(), uptime) | int %}
{%- set seconds = value | abs %}
{%- set current = value == 0 %}
{%- set future = not current and value / seconds > 0 %}
{%- set items = _just_time(seconds, language, values, biggest, short=short, floor=floor) %}
{%- if current %}
{{- items }}
{%- elif future %}
{{- translate('in', language=language) }} {{ items }}
{%- else %}
{%- set t = translate('ago', language=language) %}
{%- if '%s' in t %}
{{ t % items }}
{%- else %}
{{- items }} {{ translate('ago', language=language) }}
{%- endif %}
{%- endif %}
{%- else %}
{{- _bad_value }}
{%- endif %}
{%- endmacro %}
{# Returns the most significant time. e.g. in 3 hours #}
{%- macro easy_relative_time(uptime, attribute=None, language=None, utc=False, max_period='year', short=False, floor=False) %}
{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %}
{{- _relative_time(uptime, attribute, language, values, True, utc, short, floor) }}
{%- endmacro %}
{# Returns a large time phrase without missing any detail. e.g. in 3 hours, 4 minutes and 1 second #}
{%- macro big_relative_time(uptime, attribute=None, language=None, utc=False, max_period='year', short=False) %}
{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %}
{{- _relative_time(uptime, attribute, language, values, False, utc, short) }}
{%- endmacro %}
{# Returns a time phrase with only the details you care about most of the time. e.g. in 3 hours and 4 minutes #}
{%- macro custom_relative_time(uptime, values='', language=None, utc=False, short=False) %}
{%- set args = values.replace(' ','').split(',') | list if values is string else [] %}
{%- if args %}
{{- _relative_time(uptime, None, language, args, False, utc, short) }}
{%- else %}
{{- _relative_time(uptime, attribute, language, _default_values, False, utc, short) }}
{%- endif %}
{%- endmacro %}
{%- macro custom_relative_time_attr(uptime, attribute, values='', language=None, utc=False, short=False) %}
{%- set args = values.replace(' ','').split(',') | list if values is string else [] %}
{%- if args %}
{{- _relative_time(uptime, attribute, language, args, False, utc, short) }}
{%- else %}
{{- _relative_time(uptime, attribute, language, _default_values, False, utc, short) }}
{%- endif %}
{%- endmacro %}
{# create an iso timestamp from month number, week number, day number #}
{# Thanksgiving is 11, 4, 3 #}
{%- macro month_week_day(month, week, weekday) -%}
{%- set today = today_at() %}
{%- set temp = today.replace(month=month, day=1) %}
{%- set adjust = (weekday - temp.isoweekday()) % 7 %}
{%- set temp = temp + timedelta(days=adjust) -%}
{{ (temp + timedelta(weeks = week - 1)).isoformat() }}
{%- endmacro %}
{# create an iso timestamp from month number, day number #}
{%- macro month_day(month, day) -%}
{{ today_at().replace(month=month, day=day).isoformat() }}
{%- endmacro %}
{# create an iso timestamp on the last day of month number #}
{%- macro last_day_in_month(month, weekday) -%}
{%- set today = today_at() %}
{%- set temp = today.replace(month=month, day=1) + timedelta(days=31) %}
{%- set temp = temp.replace(day=1) - timedelta(days=7) %}
{%- set adjust = (weekday - temp.isoweekday()) % 7 %}
{%- set temp = temp + timedelta(days=adjust) -%}
{{- (temp).isoformat() }}
{%- endmacro %}
{%- macro _next_weekday(weekday, offset) %}
{%- set wd = (weekday - 1) % 7 %}
{%- set t = today_at() %}
{{- t + timedelta(days=(wd - t.weekday()) + offset) }}
{%- endmacro %}
{%- macro next_weekday(weekday) %}
{{- _next_weekday(weekday, 7) }}
{%- endmacro %}
{%- macro this_weekday(weekday) %}
{{- _next_weekday(weekday, 0) }}
{%- endmacro %}
{%- macro last_weekday(weekday) %}
{{- _next_weekday(weekday, -7) }}
{%- endmacro %}
{%- macro nearest_day(weekday) %}
{%- set today_timestamp = as_timestamp(today_at())|int %}
{%- set this_weekday_timestamp = as_timestamp(this_weekday(weekday))|int %}
{%- if today_timestamp < this_weekday_timestamp %}
{{- _next_weekday(weekday, 0) }}
{%- else %}
{{- _next_weekday(weekday, 7) }}
{%- endif %}
{%- endmacro %}
{%- macro days_in_month(month=None) %}
{%- set today = today_at() %}
{%- set input = month if month is not none else today.month %}
{%- set input = (input - 1) % 12 + 1 %}
{%- set t = today.replace(day=1, month=input) %}
{%- set inc = t.month + 1 %}
{%- set next_month = inc if inc <= 12 else 1 %}
{%- set next_year = t.year + 1 if inc > 12 else t.year %}
{%- set next = t.replace(month=next_month, year=next_year) %}
{{- (next - t).days }}
{%- endmacro %}
{%- macro _days_offset_month(offset) %}
{{- days_in_month(today_at().month + offset) }}
{%- endmacro %}
{%- macro days_next_month(offset=1) %}
{{- _days_offset_month(offset) }}
{%- endmacro %}
{%- macro days_last_month(offset=1) %}
{{- _days_offset_month(-1 * offset) }}
{%- endmacro %}
{# easter day as an iso timestamp #}
{%- macro easter() %}
{%- set year = now().year %}
{%- set special_years = ['1954', '1981', '2049', '2076'] %}
{%- set special_year_sub = 7 %}
{%- set a = year % 19 %}
{%- set b = year % 4 %}
{%- set c = year % 7 %}
{%- set d = (19 * a + 24) % 30 %}
{%- set e = ((2 * b) + (4 * c) + (6 * d) + 5) % 7 %}
{%- set day = (22 + d + e) - special_year_sub if year in special_years else 22 + d + e %}
{%- set month = 4 if day > 31 else 3 %}
{%- set day = day - 31 if day > 31 else day -%}
{{ today_at().replace(month=month, day=day).isoformat() }}
{%- endmacro %}
{%- macro _hms(t) %}
{%- set dststr = t.dst() | string if t.dst() is not none else "00:00:00" %}
{%- set h, m, s = dststr.split(':') | map('int') %}
{{- h * 60 * 60 + m * 60 + s }}
{%- endmacro %}
{%- macro _is_dst(t) %}
{{- _hms(t) | int != 0 }}
{%- endmacro %}
{%- macro _finddst(t, kwarg, rng) %}
{%- set ns = namespace(previous=_is_dst(t), found=none) %}
{%- for i in range(rng) %}
{%- set ts = t + timedelta(**{kwarg:i}) %}
{%- if ns.previous != _is_dst(ts) and ns.found is none %}
{%- set ns.found = i %}
{%- endif %}
{%- endfor %}
{{- ns.found }}
{%- endmacro %}
{# next daylight savings time #}
{%- macro next_dst() %}
{%- set t = now().replace(hour=0, minute=0, second=0, microsecond=0) %}
{%- set d = _finddst(t, 'days', 366) | int - 1 %}
{%- set h = _finddst(t + timedelta(days=d), 'hours', 25) | int - 1 %}
{%- set m = _finddst(t + timedelta(days=d, hours=h), 'minutes', 61) | int %}
{{- (t + timedelta(days=d, hours=h, minutes=m)).isoformat() }}
{%- endmacro%}
{%- macro _find_delta(t, kwarg, rng) %}
{%- set ns = namespace(previous=_hms(t), found=none) %}
{%- for i in range(rng) %}
{%- set ts = t + timedelta(**{kwarg:i}) %}
{%- if ns.previous != _hms(ts) and ns.found is none %}
{%- set before = _hms(ts - timedelta(days=1)) | int %}
{%- set after = _hms(ts) | int %}
{%- set ns.found = after - before %}
{%- endif %}
{%- endfor %}
{{- ns.found }}
{%- endmacro %}
{# What will happen next dst? #}
{% macro next_dst_phrase(language=None) %}
{%- set t = now().replace(hour=0, minute=0, second=0, microsecond=0) %}
{%- set delta = _find_delta(t, 'days', 365) | int %}
{%- if delta > 0 %}
{{- translate('lose', language=language) }} {{ easy_time_between(0, delta | abs) }}
{%- else %}
{{- translate('gain', language=language) }} {{ easy_time_between(0, delta | abs) }}
{%- endif %}
{%- endmacro %}
{# days until next dst #}
{%- macro days_until_dst() %}
{%- set next = next_dst() | as_datetime %}
{{- (next - today_at()).days if next is not none else 0 }}
{%- endmacro %}
{%- macro clock(fmat=None, language=None) %}
{{- now().strftime(_get_language_time_format(fmat, language)) }}
{%- endmacro %}
{%- set _clock_icon = ['twelve','one','two','three','four','five','six','seven','eight','nine','ten','eleven'] %}
{%- macro clock_icon(hour=None) -%}
{%- if hour is none or hour is not integer -%}
{%- set t = now() -%}
{%- set h = (t.hour + t.minute // 30) % 12 %}
{{- 'mdi:clock-time-' ~ _clock_icon[h] -}}
{%- else -%}
{{- 'mdi:clock-time-' ~ _clock_icon[hour % 12] -}}
{%- endif -%}
{%- endmacro -%}
{%- macro month(month=None, language=None, short=False) %}
{%- if month is datetime %}
{%- set idx = month.month - 1 %}
{%- elif month is integer and month > 0 %}
{%- set idx = (month - 1) % 12 %}
{%- elif month | regex_match(valid_entity_id_pattern) %}
{%- set idx = (states(month) | as_datetime | as_local).month - 1 %}
{%- else %}
{%- set idx = now().month - 1 %}
{%- endif %}
{%- set ret = translate('months', index=idx, language=language) %}
{{- ret[:3] if short else ret }}
{%- endmacro %}
{%- macro weekday(weekday=None, language=None, short=False) %}
{%- if weekday is datetime %}
{%- set idx = weekday.weekday() %}
{%- elif weekday is integer and weekday > 0 %}
{%- set idx = (weekday - 1) % 7 %}
{%- elif weekday | regex_match(valid_entity_id_pattern) %}
{%- set idx = (states(weekday) | as_datetime | as_local).weekday() %}
{%- else %}
{%- set idx = now().weekday() %}
{%- endif %}
{%- set ret = translate('days', index=idx, language=language) %}
{{- ret[:3] if short else ret }}
{%- endmacro %}
{%- macro count_the_days(input, attr, utc=False) %}
{%- set input = _to_datetime(input, attr, utc) | as_datetime | as_local %}
{%- set midnight = today_at() %}
{{- (input - midnight).days }}
{%- endmacro %}
{%- macro speak_the_days(input, attr, language=None, utc=False) %}
{%- set _days = {-1: translate('delta', 'yesterday', language=language), 0: translate('delta', 'today', language=language), 1: translate('delta', 'tomorrow', language=language)} %}
{%- set midnight = today_at() %}
{%- set ns = namespace(days=[]) %}
{%- for i in range(-7, 14) %}
{%- set prefix = translate('delta', 'last', language=language) ~ ' ' if i < -1 else translate('delta', 'next', language=language) ~ ' ' if i > 6 else '' %}
{%- set ns.days = ns.days + [ (i | string, prefix ~ _days.get(i, weekday(midnight.weekday() + (i % 7) + 1, language))) ] %}
{%- endfor %}
{%- set collection = dict.from_keys(ns.days) %}
{%- set days = count_the_days(input, attr, utc) %}
{%- if days in collection %}
{{- collection.get(days) }}
{%- else %}
{%- set days = days | int %}
{%- set ret = _phrase('day', days | abs * 86400, language, True, True) %}
{%- if days > 0 %}
{{- translate('in', language=language) }} {{ ret }}
{%- else %}
{%- set t = translate('ago', language=language) %}
{%- if '%s' in t %}
{{- t % ret }}
{%- else %}
{{- ret }} {{ translate('ago', language=language) }}
{%- endif %}
{%- endif %}
{%- endif %}
{%- endmacro %}
{%- macro hour(hour, language=None) %}
{%- if hour is datetime %}
{%- set hour = hour.hour %}
{%- elif hour | regex_match(valid_entity_id_pattern) %}
{%- set hour = (states(hour) | as_datetime | as_local).hour %}
{%- endif %}
{%- set _12 = not (hour % 12) %}
{%- set _24 = not (hour % 24) %}
{%- set use_twelve = translate('time_of_day', 'use_twelve', language=language, fallback=false) %}
{%- set _12hr = translate('time','format', language=language) == '12-hr' %}
{%- if _12 and _24 and _12hr and not use_twelve %}
{{- translate('time_of_day', 'midnight', language=language) }}
{%- elif _12 and _12hr and not use_twelve %}
{{- translate('time_of_day', 'noon', language=language) }}
{%- else %}
{%- set ret = hour % 12 if _12hr else hour %}
{{- 12 if ret == 0 and use_twelve else ret }}
{%- endif %}
{%- endmacro %}
{%- macro clock_phrase(input=None, attr=None, utc=False, language=None) %}
{%- if input is none %}
{%- set dt = now() %}
{%- elif input is datetime %}
{%- set dt = input %}
{%- else %}
{%- set dt = _to_datetime(input, attr, utc) | as_datetime %}
{%- endif %}
{%- set this_hour = dt.hour %}
{%- set this_minute = dt.minute %}
{%- if this_minute > 30 %}
{%- set hour_phrase = hour(this_hour + 1, language=language) %}
{%- set minute_calc = 60 - this_minute %}
{%- set minute_phrase = _phrase('minute', 60 * minute_calc, language, True, True) if this_minute % 5 else minute_calc | string %}
{%- else %}
{%- set hour_phrase = hour(this_hour, language=language) %}
{%- set minute_phrase = _phrase('minute', 60 * this_minute, language, True, True) if this_minute % 5 else this_minute | string %}
{%- endif %}
{%- set this_config = translate('time_of_hour', language=language) %}
{%- if (16 <= this_minute <= 29 and 'to_half_hour' in this_config) or (31 <= this_minute <= 44 and 'past_half_hour' in this_config) or (this_minute == 30 and 'half_hour' in this_config) %}
{%- set hour_phrase = hour(this_hour + 1, language=language) %}
{%- if 16 <= this_minute <= 29 %}
{%- set minute_calc = 30 - this_minute %}
{%- set fmat = translate('time_of_hour', 'to_half_hour', language=language) %}
{%- set minute_phrase = _phrase('minute', 60 * minute_calc, language, True, True) if this_minute % 5 else minute_calc | string %}
{%- elif 31 <= this_minute <= 44 %}
{%- set minute_calc = this_minute - 30 %}
{%- set fmat = translate('time_of_hour', 'past_half_hour', language=language) %}
{%- set minute_phrase = _phrase('minute', 60 * minute_calc, language, True, True) if this_minute % 5 else minute_calc | string %}
{%- else %}
{%- set minute_calc = None %}
{%- set fmat = translate('time_of_hour', 'half_hour', language=language) %}
{%- endif %}
{%- elif this_minute in [0, 1, 15, 30, 45, 59] %}
{%- if hour_phrase in ['noon', 'midnight'] and this_minute == 0 %}
{%- set fmat = '{hour}' %}
{%- else %}
{%- set fmat = translate('time_of_hour', this_minute, language=language) %}
{%- endif %}
{%- elif this_minute > 30 %}
{%- set fmat = translate('time_of_hour', 'to_hour', language=language) %}
{%- else %}
{%- set fmat = translate('time_of_hour', 'past_hour', language=language) %}
{%- endif %}
{{- fmat.format(hour=hour_phrase, minute=minute_phrase) -}}
{%- endmacro %}