246 lines
15 KiB
Django/Jinja
246 lines
15 KiB
Django/Jinja
{#
|
|
set phrases to be used in the relative_time_period macro
|
|
one list item per language, each time fraction contains a list with the singular, plural and abbriviated phrase
|
|
combine contains the text to combine the last time fraction, and error the text to display on wrong date input
|
|
#}
|
|
{%- set _time_period_phrases = [
|
|
{
|
|
'language': 'en',
|
|
'phrases':
|
|
{
|
|
'year': ['year', 'years', 'yr'],
|
|
'month': ['month', 'months', 'mth'],
|
|
'week': ['week', 'weeks', 'wk'],
|
|
'day': ['day', 'days', 'day'],
|
|
'hour': ['hour', 'hours', 'hr'],
|
|
'minute': ['minute', 'minutes', 'min'],
|
|
'second': ['second', 'seconds', 'sec'],
|
|
'millisecond': ['millisecond', 'milliseconds', 'ms'],
|
|
'combine': 'and',
|
|
'error': 'Invalid date'
|
|
}
|
|
},
|
|
{
|
|
'language': 'pl',
|
|
'phrases':
|
|
{
|
|
'year': ['rok', 'lat', 'r'],
|
|
'month': ['miesiąc', 'miesięcy', 'msc'],
|
|
'week': ['tydzień', 'tygodni', 'tyg'],
|
|
'day': ['dzień', 'dni', 'dzień'],
|
|
'hour': ['godzina', 'godzin', 'godz'],
|
|
'minute': ['minuta', 'minut', 'min'],
|
|
'second': ['sekunda', 'sekund', 'sek'],
|
|
'millisecond': ['milisekunda', 'milisekund', 'ms'],
|
|
'combine': 'i',
|
|
'error': 'Niepoprawna data'
|
|
}
|
|
},
|
|
{
|
|
'language': 'fr',
|
|
'phrases':
|
|
{
|
|
'year': ['année', 'années', 'an'],
|
|
'month': ['mois', 'mois', 'mois'],
|
|
'week': ['semaine', 'semaines', 'sem'],
|
|
'day': ['jour', 'jours', 'j'],
|
|
'hour': ['heure', 'heures', 'h'],
|
|
'minute': ['minute', 'minutes', 'min'],
|
|
'second': ['seconde', 'secondes', 'sec'],
|
|
'millisecond': ['milliseconde', 'millisecondes', 'ms'],
|
|
'combine': 'et',
|
|
'error': 'Date non valide'
|
|
}
|
|
},
|
|
{
|
|
'language': 'it',
|
|
'phrases':
|
|
{
|
|
'year': ['anno', 'anni', 'aa'],
|
|
'month': ['mese', 'mesi', 'mm'],
|
|
'week': ['settimana', 'settimane', 'set'],
|
|
'day': ['giorno', 'giorni', 'gg'],
|
|
'hour': ['ora', 'ore', 'h'],
|
|
'minute': ['minuto', 'minuti', 'min'],
|
|
'second': ['secondo', 'secondi', 'sec'],
|
|
'millisecond': ['millisecondo', 'millisecondi', 'ms'],
|
|
'combine': 'e',
|
|
'error': 'Data non valida'
|
|
}
|
|
},
|
|
{
|
|
'language': 'nl',
|
|
'phrases':
|
|
{
|
|
'year': ['jaar', 'jaar', 'jr'],
|
|
'month': ['maand', 'maanden', 'mnd'],
|
|
'week': ['week', 'weken', 'wk'],
|
|
'day': ['dag', 'dagen', 'dg'],
|
|
'hour': ['uur', 'uur', 'u'],
|
|
'minute': ['minuut', 'minuten', 'min'],
|
|
'second': ['seconde', 'seconden', 'sec'],
|
|
'millisecond': ['milliseconde', 'milliseconden', 'ms'],
|
|
'combine': 'en',
|
|
'error': 'Ongeldige datum'
|
|
}
|
|
},
|
|
{
|
|
'language': 'de',
|
|
'phrases':
|
|
{
|
|
'year': ['Jahr', 'Jahre', 'J.'],
|
|
'month': ['Monat', 'Monate', 'M.'],
|
|
'week': ['Woche', 'Wochen', 'Wo.'],
|
|
'day': ['Tag', 'Tage', 'Tg.'],
|
|
'hour': ['Stunde', 'Stunden', 'Std.'],
|
|
'minute': ['Minute', 'Minuten', 'Min.'],
|
|
'second': ['Sekunde', 'Sekunden', 'Sek.'],
|
|
'millisecond': ['Milliseconde', 'Milliseconden', 'ms'],
|
|
'combine': 'und',
|
|
'error': 'Falsches Datum'
|
|
}
|
|
},
|
|
{
|
|
'language': 'pt',
|
|
'phrases':
|
|
{
|
|
'year': ['ano', 'anos', 'aa'],
|
|
'month': ['mês', 'meses', 'mm'],
|
|
'week': ['semana', 'semanas', 'sem'],
|
|
'day': ['dia', 'dias', 'd'],
|
|
'hour': ['hora', 'horas', 'h'],
|
|
'minute': ['minuto', 'minutos', 'min'],
|
|
'second': ['segundo', 'segundos', 'seg'],
|
|
'millisecond': ['millissegundo', 'millissegundos', 'ms'],
|
|
'combine': 'e',
|
|
'error': 'Data Inválida'
|
|
}
|
|
},
|
|
{
|
|
'language': 'dk',
|
|
'phrases':
|
|
{
|
|
'year': ['år', 'år', 'år'],
|
|
'month': ['måned', 'måneder', 'mnd'],
|
|
'week': ['uge', 'uger', 'uge'],
|
|
'day': ['dag', 'dage', 'dag'],
|
|
'hour': ['time', 'timer', 't.'],
|
|
'minute': ['minut', 'minuter', 'min.'],
|
|
'second': ['sekund', 'sekunder', 'sek.'],
|
|
'millisecond': ['millisekund', 'millisekunder', 'ms.'],
|
|
'combine': 'og',
|
|
'error': 'Ugyldig dato'
|
|
}
|
|
}
|
|
]
|
|
%}
|
|
|
|
{#
|
|
macro to split a timedelta in years, months, weeks, days, hours, minutes, seconds
|
|
used by the relative time plus macro, set up as a seperate macro so it can be reused
|
|
#}
|
|
{%- macro time_split(date, compare_date=now(), time=true, not_use=[]) -%}
|
|
{# set defaults for variables #}
|
|
{%- set date = date | as_local if time else date.date()-%}
|
|
{%- set time = time | bool(true) -%}
|
|
{%- set comp_date = compare_date if time else compare_date.date() -%}
|
|
{%- set date_max = [comp_date, date] | max -%}
|
|
{%- set date_min = [comp_date, date] | min -%}
|
|
{#- set time periods in seconds #}
|
|
{%- set m, h, d, w = 60, 3600, 86400, 604800 -%}
|
|
{#- set numer of years, and set lowest date using this number of years #}
|
|
{%- set yrs = date_max.year - date_min.year - (1 if date_max.replace(year=date_min.year) < date_min else 0) -%}
|
|
{%- set date_max = date_max.replace(year=date_max.year - yrs) -%}
|
|
{#- set numer of months, and set lowest date using this number of months #}
|
|
{%- if 'month' not in not_use -%}
|
|
{%- set mth = (date_max.month - date_min.month - (1 if date_max.day < date_min.day else 0) + 12) % 12 -%}
|
|
{%- set month_new = (((date_max.month - mth) + 12) % 12) | default(12, true) -%}
|
|
{%- set day_max = ((date_max.replace(day=1, month=month_new) + timedelta(days=31)).replace(day=1) - timedelta(days=1)).day -%}
|
|
{%- set extra_days = [0, date_max.day - day_max] | max -%}
|
|
{%- set date_temp = date_max.replace(month=month_new, day=[date_max.day, day_max]|min) -%}
|
|
{%- set date_max = date_temp if date_temp <= date_max else date_temp.replace(year=date_max.year-1) -%}
|
|
{%- set mth = mth + yrs * 12 if 'year' in not_use else mth -%}
|
|
{%- endif -%}
|
|
{%- set date_max = date_max.replace(year=date_max.year + yrs) if 'year' in not_use and 'month' in not_use else date_max -%}
|
|
{%- set yrs = 0 if 'year' in not_use else yrs -%}
|
|
{#- set other time period variables #}
|
|
{%- set s = (date_max - date_min).total_seconds() + extra_days | default(0) * 86400 -%}
|
|
{%- set wks = 0 if 'week' in not_use else (s // w) | int -%}
|
|
{%- set day = 0 if 'day' in not_use else ((s - wks * w) // d) | int -%}
|
|
{%- set hrs = 0 if 'hour' in not_use else ((s - wks * w - day * d) // h) | int -%}
|
|
{%- set min = 0 if 'minute' in not_use else ((s - wks * w - day * d - hrs * h) // m) | int -%}
|
|
{%- set sec = 0 if 'second' in not_use else (s - wks * w - day * d - hrs * h - min * m) | int -%}
|
|
{%- set ms = (s % 1 * 1000) | round | int -%}
|
|
{# output result #}
|
|
{%- set output = dict(year=yrs, month=mth | default(0), week=wks, day=day, hour=hrs, minute=min, second=sec, millisecond=ms) %}
|
|
{{- dict(output.items() | rejectattr('0', 'in', not_use)) | to_json -}}
|
|
{%- endmacro -%}
|
|
|
|
{# macro to output a timedelta in a readable format #}
|
|
{%- macro relative_time_plus(date, parts=1, abbr=false, verbose=false, language='en', compare_date=now(), month=none, week=none, millisecond=none, not_use=['millisecond'], always_show=[], time=true) -%}
|
|
{#- set defaults for input if not entered #}
|
|
{%- set date = date if date is datetime else date | as_datetime -%}
|
|
{%- set compare_date = compare_date if compare_date is datetime else compare_date | as_datetime -%}
|
|
{#- select correct phrases bases on language input #}
|
|
{%- set phrases = _time_period_phrases -%}
|
|
{%- set languages = phrases | map(attribute='language') | list -%}
|
|
{%- set language = iif(language in languages, language, 'en') -%}
|
|
{%- set phr = phrases | selectattr('language', 'eq', language) | map(attribute='phrases') | list | first -%}
|
|
{#- perform smart stuff #}
|
|
{%- if date is datetime and compare_date is datetime -%}
|
|
{# determine not_use list #}
|
|
{%- set abbr_to_full = dict(yr='year', mth='month', wk='week', hr='hour', min='minute', sec='second', ms='millisecond') -%}
|
|
{%- set add = [('month', month),('week',week),('millisecond',millisecond)] | selectattr('1', 'eq', false) | map(attribute='0') | list -%}
|
|
{%- set not_use = not_use if not_use is list else (not_use | replace(' ', '')).split(',') -%}
|
|
{%- set not_use = (not_use + add) | unique | list -%}
|
|
{%- if not_use | select('in', abbr_to_full) | list | count > 0 -%}
|
|
{%- set ns = namespace(not_use=[]) -%}
|
|
{%- for i in not_use -%}
|
|
{%- set ns.not_use = ns.not_use + [abbr_to_full[i] | default(i)] -%}
|
|
{%- endfor -%}
|
|
{%- set not_use = ns.not_use | unique | list -%}
|
|
{%- endif -%}
|
|
{# set variables #}
|
|
{%- set date, compare_date = date | as_local, compare_date | as_local -%}
|
|
{%- set parts = parts | int(1) -%}
|
|
{%- set time = time | bool(true) -%}
|
|
{%- set abbr = abbr | bool(false) or verbose | bool(false) -%}
|
|
{# split timedelta #}
|
|
{%- set time_parts = time_split(date, compare_date, time, not_use) | from_json -%}
|
|
{#- find first non zero time period #}
|
|
{%- set time_periods = ['year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'] -%}
|
|
{%- set do_use = time_periods | reject('in', not_use) | list -%}
|
|
{# continue if there are still time periods to use #}
|
|
{%- if do_use | count > 0 -%}
|
|
{%- set always_return = do_use | last -%}
|
|
{%- set always_show = always_show if always_show is list else (always_show | replace(' ', '')).split(',') -%}
|
|
{%- if always_show | select('in', abbr_to_full) | list | count > 0 -%}
|
|
{%- set ns = namespace(always_show=[]) -%}
|
|
{%- for i in always_show -%}
|
|
{%- set ns.always_show = ns.always_show + [abbr_to_full[i] | default(i)] -%}
|
|
{%- endfor -%}
|
|
{%- set always_show = ns.always_show | unique | list -%}
|
|
{%- endif -%}
|
|
{%- set parts = [parts, always_show | count] | max -%}
|
|
{%- set to_show = (time_parts.items() | selectattr('1') | map(attribute='0') | list + always_show) | unique | list | default([always_return], true) -%}
|
|
{%- set first = do_use | select('in', to_show) | first -%}
|
|
{#-select itemw to show based on input #}
|
|
{%- set index_first = (time_parts.keys() | list).index(first) -%}
|
|
{%- set items = (time_parts.keys() | list)[index_first:index_first + parts] -%}
|
|
{# convert to phrases #}
|
|
{%- set ns = namespace(phrases=[]) -%}
|
|
{%- for i in items if i in to_show or i == first -%}
|
|
{%- set phr_abbr = phr[i][2] -%}
|
|
{%- set phr_verb = phr[i][1] if time_parts[i] != 1 else phr[i][0] -%}
|
|
{%- set phrase = '{} {}'.format(time_parts[i], phr_abbr if abbr else phr_verb) -%}
|
|
{%- set ns.phrases = ns.phrases + [phrase] -%}
|
|
{%- endfor -%}
|
|
{#- join phrases in a string, using phr.combine for the last item #}
|
|
{{- '{} {} {}'.format(ns.phrases[:-1] | join(', '), phr.combine, ns.phrases[-1]) if ns.phrases | count > 1 else ns.phrases | first -}}
|
|
{%- else -%}
|
|
All time periods are excluded
|
|
{%- endif -%}
|
|
{%- else -%}
|
|
{{- phr.error -}}
|
|
{%- endif -%}
|
|
{%- endmacro -%} |