<p>I made a Craft plugin that simply wraps PHP DatePeriod: <a href="https://github.com/carlcs/craft-dateperiod" rel="nofollow">"Date Period plugin for Craft"</a>. The plugin provides a <code>datePeriod</code> Twig function. It works really simple, your give it a start date, an end date and an interval to create a DatePeriod object.</p>

<pre><code>datePeriod( startDate, endDate, interval )
</code></pre>

<p>This DatePeriod object you can now iterate over to get the dates, recurring at the set interval, over the period spanning your start and end date. By default the interval is set to 1 day, but you can modify that with the (optional) parameter. </p>

<pre><code>{% set datePeriod = datePeriod(startDate, endDate, '1 month') %}

{% for month in datePeriod %}
    {{ month|date('F') }}
{% endfor %}
</code></pre>

<p>To also list the days in between, you would add Craft's <code>group</code> filter like so:</p>

<pre><code>{% set datePeriod = datePeriod(startDate, endDate) %}

{% for month, daysInMonth in datePeriod|group('{ object|date("F") }') %}
    {{ month }}
    {% for day in daysInMonth %}
        {{ day|date('d') }}
    {% endfor %}
{% endfor %}
</code></pre>

CC BY-SA 3.0
2015-05-06T20:07:58.623Z
2015-05-07T05:27:14.130Z
2015-05-07T05:27:14.130Z
carlcs
<p>Ok, there must be a better way, but if you want to also show the days eventually, try this approach (As hinted by <a href="https://stackoverflow.com/questions/24078884/twig-date-loop-each-day-in-a-period">this answer</a>, you basically loop through the seconds, in steps of 86400 (= one day)):</p>

<pre><code>{% set start = craft.plugin.getStartDate() %} // returns 5/4/2015
{% set end = craft.plugin.getEndData() %} // returns 9/25/2015

{% set currentMonth = null %}
{% for day in range(start | date('U'), end | date('U'), 86400) %}
    {% set month = day | date('F') %} {# create a month variable #}
    {% if month != currentMonth %}
        {{ month }} {# display the month, once #}
        {% set currentMonth = month %}
    {% endif %}

    {{ day | date('d') }} {# display the day #}
{% endfor %}
</code></pre>

CC BY-SA 3.0
2015-05-07T13:41:45.477Z
Ah - I had looked at the thread you linked to - this is where I was going wrong: `{% if month != currentMonth %}...{%endif%}`
Damon
CC BY-SA 3.0
2015-05-06T18:01:04.910Z
2015-05-06T18:07:35.320Z
2017-05-23T12:38:53.957Z
Paul
<p>I have this macro in my _macros/_utils.html:</p>

<pre><code>{% macro monthNameFromNumber(monthNumber) %}
  {# monthNumber will be 00-12. we use that to construct a date string,
     convert it to date and then pick the month name out of that #}
  {{ date('2014-' ~ monthNumber ~ '-01') | date('F') }}
{% endmacro %}
</code></pre>

<p>You can use it like this:</p>

<pre><code>{% import _macros/utils as m_utils %}

{% for month in range(startMonth, endMonth, 1) %}
  {{ m_utils.monthNameFromNumber(month) }}
{% endfor %}
</code></pre>

CC BY-SA 3.0
2015-05-07T21:56:20.763Z
2015-05-07T21:56:20.763Z
Marion Newlevant
<p>You could solve this with a recursive macro and add a day / month to the <code>startDate</code> with each iteration:</p>

<pre><code>{% macro listDays(startDate, endDate) %}
    {% import _self as self %}

    {% if startDate &lt;= endDate %}
        {{ startDate|date('F-d') }}
        {{ self.listDays(startDate|date_modify('+ 1 day'), endDate) }}
    {% endif %}

{% endmacro %}
</code></pre>

<p>And then call it like so:</p>

<pre><code>{{ macros.listDays(startDate, endDate) }}
</code></pre>

CC BY-SA 3.0
2015-05-06T18:09:48.240Z
2015-05-06T18:31:26.873Z
2015-05-06T18:31:26.873Z
carlcs
<p>I am trying to list the months (January, Febuary etc) between two dates.
I have a start date: <code>5/4/2015</code> and an end date: <code>9/25/2015</code>.</p>

<p>Using <a href="http://twig.sensiolabs.org/doc/functions/range.html" rel="nofollow">range</a> I am able to return the month numbers, but just can't figure out the correct syntax to convert <code>5</code> into <code>May</code>.</p>

<p>Here's what I've got so far, maybe there is a better way all together?</p>

<p><strong>TWIG</strong></p>

<pre><code>{% set startMonth = craft.plugin.getStartDate() %} // returns 5/4/2015
{% set endMonth = craft.plugin.getEndData() %} // returns 9/25/2015

{% for month in range(startMonth, endMonth, 1) %}
    {{ month }}  // returns 5 6 7 8 9
{% endfor %}
</code></pre>

<p>I've tried doing something like: <code>{{ month|date('F') }}</code> but that returns <code>December</code> for each result. </p>

<p>I'll eventually need days within this month range, but I am hoping from this I can figure that out.</p>

CC BY-SA 3.0
2015-05-07T13:40:43.997Z
Thank you everyone - these are all so great. I wish there was a way to accept all answers!
Damon
<templating><datetime>
List months between a given date range
# List months between a given date range

(Asked by: username_0 on 2015-05-06)

I am trying to list the months (January, Febuary etc) between two dates.
I have a start date: 5/4/2015 and an end date: 9/25/2015.
Using range I am able to return the month numbers, but just can't figure out the correct syntax to convert 5 into May.
Here's what I've got so far, maybe there is a better way all together?
TWIG
{% set startMonth = craft.plugin.getStartDate() %} // returns 5/4/2015
{% set endMonth = craft.plugin.getEndData() %} // returns 9/25/2015

{% for month in range(startMonth, endMonth, 1) %}
    {{ month }}  // returns 5 6 7 8 9
{% endfor %}

I've tried doing something like: {{ month|date('F') }} but that returns December for each result. 
I'll eventually need days within this month range, but I am hoping from this I can figure that out.

**Tags:** templating, datetime

> **Comments:**
> **username_0**: Thank you everyone - these are all so great. I wish there was a way to accept all answers!  

---

## 4 answers

### Answer by username_1 on 2015-05-06. Score: 3

I made a Craft plugin that simply wraps PHP DatePeriod: "Date Period plugin for Craft". The plugin provides a datePeriod Twig function. It works really simple, your give it a start date, an end date and an interval to create a DatePeriod object.
datePeriod( startDate, endDate, interval )

This DatePeriod object you can now iterate over to get the dates, recurring at the set interval, over the period spanning your start and end date. By default the interval is set to 1 day, but you can modify that with the (optional) parameter. 
{% set datePeriod = datePeriod(startDate, endDate, '1 month') %}

{% for month in datePeriod %}
    {{ month|date('F') }}
{% endfor %}

To also list the days in between, you would add Craft's group filter like so:
{% set datePeriod = datePeriod(startDate, endDate) %}

{% for month, daysInMonth in datePeriod|group('{ object|date("F") }') %}
    {{ month }}
    {% for day in daysInMonth %}
        {{ day|date('d') }}
    {% endfor %}
{% endfor %}


---

### Answer by username_2 on 2015-05-06. Score: 2

Ok, there must be a better way, but if you want to also show the days eventually, try this approach (As hinted by this answer, you basically loop through the seconds, in steps of 86400 (= one day)):
{% set start = craft.plugin.getStartDate() %} // returns 5/4/2015
{% set end = craft.plugin.getEndData() %} // returns 9/25/2015

{% set currentMonth = null %}
{% for day in range(start | date('U'), end | date('U'), 86400) %}
    {% set month = day | date('F') %} {# create a month variable #}
    {% if month != currentMonth %}
        {{ month }} {# display the month, once #}
        {% set currentMonth = month %}
    {% endif %}

    {{ day | date('d') }} {# display the day #}
{% endfor %}

> **Comments:**
> **username_0**: Ah - I had looked at the thread you linked to - this is where I was going wrong: `{% if month != currentMonth %}...{%endif%}`  

---

### Answer by username_3 on 2015-05-07. Score: 2

I have this macro in my _macros/_utils.html:
{% macro monthNameFromNumber(monthNumber) %}
  {# monthNumber will be 00-12. we use that to construct a date string,
     convert it to date and then pick the month name out of that #}
  {{ date('2014-' ~ monthNumber ~ '-01') | date('F') }}
{% endmacro %}

You can use it like this:
{% import _macros/utils as m_utils %}

{% for month in range(startMonth, endMonth, 1) %}
  {{ m_utils.monthNameFromNumber(month) }}
{% endfor %}


---

### Answer by username_1 on 2015-05-06. Score: 2

You could solve this with a recursive macro and add a day / month to the startDate with each iteration:
{% macro listDays(startDate, endDate) %}
    {% import _self as self %}

    {% if startDate <= endDate %}
        {{ startDate|date('F-d') }}
        {{ self.listDays(startDate|date_modify('+ 1 day'), endDate) }}
    {% endif %}

{% endmacro %}

And then call it like so:
{{ macros.listDays(startDate, endDate) }}


---

