10

Let's say you have two dates and want to output the timeframe in fully written "day month year - day month year" notation, but want to leave out the month and year parts of the start date if unnecessary.

Examples:

  • 2014-06-13 to 2014-06-20 yields 13 – 20 June 2014
  • 2014-06-13 to 2014-07-13 yields 13 June – 13 July 2014
  • 2014-06-13 to 2015-06-13 yields 13 June 2014 – 13 June 2015

How can I get the desired notation of the timeframe?

16

Add the following macro to your template or import it with a separate twig file. The script allows the start and end date to be the same and outputs a single date instead of a timeframe.

Example:

2014-06-13 to 2014-06-13 yields 13 June 2014

The macro:

{% macro timeframe(dateStart, dateEnd) %}

    {# Output day of the start date if necessary #}
    {{ dateStart != dateEnd ? dateStart|date('j') }}

    {# Output month of the start date if necessary #}
    {{ dateStart|date('FY') != dateEnd|date('FY') ? dateStart|date('F') }}

    {# Output year of the start date if necessary #}
    {{ dateStart|date('Y') != dateEnd|date('Y') ? dateStart|date('Y') }}

    {# Output a hyphen if necessary #}
    {{ dateStart != dateEnd ? ' - ' }}

    {# Output end date #}
    {{ dateEnd|date('j F Y') }}

{% endmacro %}

Example usage:

{# Import external `macros.html` #}
{% import "macros.html" as macros %}

{# Call the macro #}
{% macros.timeframe(entry.exhibitionDateStart, entry.exhibitionDateEnd) %}

.

Edit:

Updated the macro to additionally support "month day, year" notation. The returned notation depends on the localeId attribute passed to the macro (eg. "en_us"). But you probably want to use the current locale's id, craft.locale for that ;)

Examples:

  • 2014-06-13 to 2014-06-13 yields June 13, 2014
  • 2014-06-13 to 2014-06-20 yields June 13 – 20, 2014
  • 2014-06-13 to 2014-07-13 yields June 13 – July 13, 2014
  • 2014-06-13 to 2015-06-13 yields June 13, 2014 – June 13, 2015

The updated macro:

{% macro timeframe(dateStart, dateEnd, localeId) %}

    {# Define locales where 'j. F - j. F Y' format is desired #}
    {% set locales_jFY = ['de', 'it', none] %}

    {# Define locales where 'F j. - F j., Y' format is desired #}
    {% set locales_FjY  = ['en'] %}

    {# Return timeframe for `locales_jFY` locales #}
    {% if localeId in locales_jFY %}

        {# Output day of the start date if necessary #}
        {{- dateStart != dateEnd ? dateStart|date('j. ') -}}

        {# Output month of the start date if necessary #}
        {{- dateStart|date('FY') != dateEnd|date('FY') ? dateStart|date('F ') -}}

        {# Output year of the start date if necessary #}
        {{- dateStart|date('Y') != dateEnd|date('Y') ? dateStart|date('Y') -}}

        {# Output a hyphen if necessary #}
        {{- dateStart != dateEnd ? ' - ' -}}

        {# Output end date #}
        {{- dateEnd|date('j. F Y') -}}

    {# Return timeframe for `locales_FjY` locales #}
    {% elseif localeId in locales_FjY %}

        {# Check if dates are on the same day but in different years #}
        {% if (dateStart|date('Fj') == dateEnd|date('Fj')) and (dateStart|date('Y') != dateEnd|date('Y')) %}
            {% set sameDaydiffYear = true %}
        {% endif %}

        {# Output month and day of the start date #}
        {{- dateStart|date('F j') -}}

        {# Output year of the start date if necessary #}
        {{- dateStart|date('Y') != dateEnd|date('Y') ? dateStart|date(', Y') -}}

        {# Output a hyphen if necessary #}
        {{- dateStart != dateEnd ? ' - ' -}}

        {# Output month of the end date if necessary #}
        {{- dateStart|date('F') != dateEnd|date('F') or sameDaydiffYear ? dateEnd|date('F ') -}}

        {# Output day of the end date if necessary #}
        {{- dateStart|date('Fj') != dateEnd|date('Fj') or sameDaydiffYear ? dateEnd|date('j') -}}

        {# Output year of the end date #}
        {{- dateEnd|date(', Y') -}}

    {% endif %}

{% endmacro %}
| improve this answer | |
  • This is a fantastic example, thanks for answering yourself! I apparently need to be using more macros. – Matt Stein Jun 13 '14 at 20:01
  • Thanks for your kind feedback, @Matt. I take that as a permission to accept my own answer! :) Have to wait 2 days though.. – carlcs Jun 13 '14 at 20:13
  • It is, without a doubt, the best answer to this question. – Matt Stein Jun 13 '14 at 20:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.