{%- 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', ], 'time_of_hour':{ 0: '{hour}', 1: '{hour} e un minuto', 15: '{hour} ed un quarto', 30: '{hour} e mezzo', 45: '15 minuti alle {hour}', 59: 'un minuto alle {hour}', 'past_hour': '{hour} e {minute}', 'to_hour': '{hour} meno {minute}', }, 'time_of_day':{ 'midnight': 'mezzanotte', 'noon': 'mezzogiorno', } }, '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ń', ], 'time_of_hour': { 0: '{hour}', 1: 'minuta po {hour}', 15: 'kwadrans po {hour}', 30: 'pół godziny po {hour}', 45: 'za kwadrans {hour}', 59: 'za minutę {hour}', 'past_hour': '{minute} po {hour}', 'to_hour': '{minute} do {hour}' }, 'time_of_day': { 'midnight': 'północ', 'noon': 'południe' } }, '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_]+(? 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 }} {{ t }} {%- 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 }} {{ t }} {%- 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 %}