<p>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.</p>

<p>Example:</p>

<p><code>2014-06-13</code> to <code>2014-06-13</code> yields <code>13 June 2014</code></p>

<p>The macro:</p>

<pre><code>{% 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 %}
</code></pre>

<p>Example usage:</p>

<pre><code>{# Import external `macros.html` #}
{% import "macros.html" as macros %}

{# Call the macro #}
{% macros.timeframe(entry.exhibitionDateStart, entry.exhibitionDateEnd) %}
</code></pre>

<p>.</p>

<p><strong><em>Edit:</em></strong></p>

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

<p>Examples:</p>

<ul>
<li><code>2014-06-13</code> to <code>2014-06-13</code> yields <code>June 13, 2014</code></li>
<li><code>2014-06-13</code> to <code>2014-06-20</code> yields <code>June 13 – 20, 2014</code></li>
<li><code>2014-06-13</code> to <code>2014-07-13</code> yields <code>June 13 – July 13, 2014</code></li>
<li><code>2014-06-13</code> to <code>2015-06-13</code> yields <code>June 13, 2014 – June 13, 2015</code></li>
</ul>

<p>The updated macro:</p>

<pre><code>{% 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 %}
</code></pre>

CC BY-SA 3.0
2014-06-13T20:01:15.043Z
This is a fantastic example, thanks for answering yourself! I apparently need to be using more macros.
Matt Stein
CC BY-SA 3.0
2014-06-13T20:13:46.173Z
Thanks for your kind feedback, @Matt. I take that as a permission to accept my own answer! :) Have to wait 2 days though..
carlcs
CC BY-SA 3.0
2014-06-13T20:14:44.873Z
It is, without a doubt, the best answer to this question.
Matt Stein
CC BY-SA 3.0
2014-06-13T19:22:32.083Z
2014-07-14T20:48:36.250Z
2014-07-14T20:48:36.250Z
carlcs
<p>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.</p>

<p>Examples:</p>

<ul>
<li><code>2014-06-13</code> to <code>2014-06-20</code> yields <code>13 – 20 June 2014</code></li>
<li><code>2014-06-13</code> to <code>2014-07-13</code> yields <code>13 June – 13 July 2014</code></li>
<li><code>2014-06-13</code> to <code>2015-06-13</code> yields <code>13 June 2014 – 13 June 2015</code></li>
</ul>

<p>How can I get the desired notation of the timeframe?</p>

<datetime><format>
How can I output a timeframe in fully written notation nicely?
# How can I output a timeframe in fully written notation nicely?

(Asked by: username_0 on 2014-06-13)

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?

**Tags:** datetime, format

---

## 1 answers

### Answer by username_0 on 2014-06-13. Score: 16 | Accepted answer

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 %}

> **Comments:**
> **username_1**: This is a fantastic example, thanks for answering yourself! I apparently need to be using more macros.  
> **username_0**: Thanks for your kind feedback, @Matt. I take that as a permission to accept my own answer! :) Have to wait 2 days though..  
> **username_1**: It is, without a doubt, the best answer to this question.  

---

