<p>I think I have a solution to this problem, but it's kind of complicated. There may be a way to simplify this more.</p>

<p>The basic idea is to loop thru your Store Hours field (<code>entry.hoursOfOperation</code>) and build a new array (<code>storeHours</code>) where the days are combined if the current loop's open and close times match the previous loop's.</p>

<pre class="lang-twig prettyprint-override"><code>{% set days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] %}
{% set daysShort = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'] %}

{# Setup a new array storeHours to hold all you hashes 
   and prev variables to compare things to in the loop 
 #}
{% set storeHours, prevDays, prevDaysShort, prevOpen, prevClose = [],[],[],"","" %}

{# Loop thru your Store Hours field and build the storeHours array #}
{% for item in entry.hoursOfOperation %}

  {# in the first loop, setup the prevOpen and prevClose variables  #}
  {% if loop.first %}
    {% set prevOpen, prevClose = item.open, item.close %}
  {% endif %}

  {# If the prev hours match the current item's hours, 
     add that day's name to the array of prev days, ["Monday","Tuesday"] etc.
   #}
  {% if prevOpen == item.open and prevClose == item.close %}
    {% set prevDays = prevDays|merge([days[loop.index0]]) %}
    {% set prevDaysShort = prevDaysShort|merge([daysShort[loop.index0]]) %}

  {# If it doesn’t match, add prev variables as a hash to the storeHours array,
     Then set all prev variables with current item
   #}
  {% else %}

    {% set storeHours = storeHours|merge([{
      "days" : prevDays,
      "daysShort" : prevDaysShort,
      "open" : prevOpen,
      "close" : prevClose
    }]) %}

    {% set prevDays = [days[loop.index0]] %}
    {% set prevDaysShort = [daysShort[loop.index0]] %}
    {% set prevOpen = item.open %}
    {% set prevClose = item.close %}

  {% endif %}

  {# If last loop, add prev variables as a hash to the storeHours array
     because there won’t be another loop to compare it to.
   #}
  {% if loop.last %}
    {% set storeHours = storeHours|merge([{
      "days" : prevDays,
      "daysShort" : prevDaysShort,
      "open" : prevOpen,
      "close" : prevClose
    }]) %}
  {% endif %}

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

<p>The <code>storeHours</code> data format will be something like this:</p>

<pre class="lang-json prettyprint-override"><code>[
  {
    "days" : ["Monday", "Tuesday", "Wednesday"],
    "daysShort" : ["Mo","Tu","We"],
    "open" : "2017-01-21 09:30:00.000000",
    "close" : "2017-01-21 21:00:00.000000"
  },
  {
    "days" : ["Thursday","Friday"],
    "daysShort" : ["Th","Fr"],
    "open" : "2017-01-21 09:00:00.000000",
    "close" : "2017-01-21 17:00:00.000000"
  }
]
</code></pre>

<p>Once you've created your <code>storeHours</code> array, you can use it to output your HTML code.</p>

<pre class="lang-html prettyprint-override"><code>&lt;dl class="store-details-hours__list"&gt;
  {% for item in storeHours %}

    &lt;dt class="store-details-hours__day"&gt;
      {{ item.days|first }}{% if item.days|length &gt; 1 %} - {{ item.days|last }}{% endif %}
    &lt;/dt&gt;    

    {% if item.open|length and item.close|length %}
      &lt;dd class="store-details-hours__hours" itemprop="openingHours" 
        content="{{ item.daysShort|join(',') }} {{ item.open|date('h:i') }} - {{ item.close|date('h:i') }}"&gt;
        {{ item.open|date('h:i a') }} - {{ item.close|date('h:i a') }}
      &lt;/dd&gt;
    {% else %}
      &lt;dd class="store-details-hours__hours" itemprop="openingHours" 
        content="{{ item.daysShort|join(',') }} Closed"&gt;
        Closed
      &lt;/dd&gt;
    {% endif %}

  {% endfor %}
&lt;/dl&gt;
</code></pre>

<hr>

<p><strong>BONUS ROUND:</strong> if you want to make <strong>Monday the first day of the week</strong>, reorder the <code>days</code> and <code>daysShort</code> arrays at the top like this:</p>

<pre class="lang-twig prettyprint-override"><code>{% set days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] %}
{% set daysShort = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'] %}
</code></pre>

<p>Then add this line just below it:</p>

<pre class="lang-twig prettyprint-override"><code>{% set hoursMondayFirst = entry.hoursOfOperation|slice(1,entry.hoursOfOperation|length)|merge(entry.hoursOfOperation|slice(0,1)) %}
</code></pre>

<p>That makes a new variable using <a href="http://twig.sensiolabs.org/doc/1.x/filters/slice.html" rel="nofollow noreferrer">Twig's slice filter</a> to take Monday - Saturday (<code>slice(1|length)</code>) and merge Sunday at the end (<code>slice(0,1)</code>).</p>

<p>Now just use this as the start of your loop:</p>

<pre class="lang-twig prettyprint-override"><code>{% for item in hoursMondayFirst %}
</code></pre>

CC BY-SA 3.0
2017-01-23T18:40:56.707Z
Will try this a little later. Agree it is a little complex.
CreateSean
CC BY-SA 3.0
2017-01-21T22:14:50.790Z
2017-11-20T20:42:26.287Z
2017-11-20T20:42:26.287Z
Alex Roper
<p>I'm using the Store Hours plugin to output store hours like this:</p>

<pre class="lang-html prettyprint-override"><code>{% set days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] %}
{% set daysShort = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'] %}

&lt;dl class="store-details-hours__list"&gt;
  {% for dayHours in entry.hoursOfOperation %}
    &lt;dt class="store-details-hours__day"&gt;{{ days[loop.index0] }}&lt;/dt&gt;

    {% if dayHours.open|length and dayHours.close|length %}

      &lt;dd class="store-details-hours__hours"
        itemprop="openingHours" content="{{ daysShort[loop.index0] }} {{ dayHours.open|date('h:i') }} - {{ dayHours.close|date('h:i') }}"&gt;{{ dayHours.open|date('h:i a') }} - {{ dayHours.close|date('h:i a') }}&lt;/dd&gt;
    {% else %}
    &lt;dd class="store-details-hours__hours"
      itemprop="openingHours" content="{{ daysShort[loop.index0] }} Closed"&gt;Closed&lt;/dd&gt;
    {% endif %}
  {% endfor %}

&lt;/dl&gt;
</code></pre>

<p>This works okay and outputs like this:</p>

<p><a href="https://i.sstatic.net/3NkS4.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/3NkS4.jpg" alt="enter image description here"></a></p>

<p>But what I really need is to be able to group the days if the hours are the same so that it looks like this:</p>

<p><a href="https://i.sstatic.net/RjYJG.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/RjYJG.jpg" alt="enter image description here"></a></p>

<p>It's also important that I can set an attribute tag on the <code>&lt;dd&gt;</code> of <code>content="Mo,Tu,We, 10:00-17:00"</code> So how do I group days of the week and output the hours the way my client wants it to look?</p>

<templating><plugins>
Store Hours (group days by hours)
# Store Hours (group days by hours)

(Asked by: username_0 on 2017-01-16)

I'm using the Store Hours plugin to output store hours like this:
{% set days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] %}
{% set daysShort = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'] %}


  {% for dayHours in entry.hoursOfOperation %}
    {{ days[loop.index0] }}

    {% if dayHours.open|length and dayHours.close|length %}

      {{ dayHours.open|date('h:i a') }} - {{ dayHours.close|date('h:i a') }}
    {% else %}
    Closed
    {% endif %}
  {% endfor %}



This works okay and outputs like this:

But what I really need is to be able to group the days if the hours are the same so that it looks like this:

It's also important that I can set an attribute tag on the  of content="Mo,Tu,We, 10:00-17:00" So how do I group days of the week and output the hours the way my client wants it to look?

**Tags:** templating, plugins

---

## 1 answers

### Answer by username_1 on 2017-01-21. Score: 6 | Accepted answer

I think I have a solution to this problem, but it's kind of complicated. There may be a way to simplify this more.
The basic idea is to loop thru your Store Hours field (entry.hoursOfOperation) and build a new array (storeHours) where the days are combined if the current loop's open and close times match the previous loop's.
{% set days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] %}
{% set daysShort = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'] %}

{# Setup a new array storeHours to hold all you hashes 
   and prev variables to compare things to in the loop 
 #}
{% set storeHours, prevDays, prevDaysShort, prevOpen, prevClose = [],[],[],"","" %}

{# Loop thru your Store Hours field and build the storeHours array #}
{% for item in entry.hoursOfOperation %}

  {# in the first loop, setup the prevOpen and prevClose variables  #}
  {% if loop.first %}
    {% set prevOpen, prevClose = item.open, item.close %}
  {% endif %}

  {# If the prev hours match the current item's hours, 
     add that day's name to the array of prev days, ["Monday","Tuesday"] etc.
   #}
  {% if prevOpen == item.open and prevClose == item.close %}
    {% set prevDays = prevDays|merge([days[loop.index0]]) %}
    {% set prevDaysShort = prevDaysShort|merge([daysShort[loop.index0]]) %}

  {# If it doesn’t match, add prev variables as a hash to the storeHours array,
     Then set all prev variables with current item
   #}
  {% else %}

    {% set storeHours = storeHours|merge([{
      "days" : prevDays,
      "daysShort" : prevDaysShort,
      "open" : prevOpen,
      "close" : prevClose
    }]) %}

    {% set prevDays = [days[loop.index0]] %}
    {% set prevDaysShort = [daysShort[loop.index0]] %}
    {% set prevOpen = item.open %}
    {% set prevClose = item.close %}

  {% endif %}

  {# If last loop, add prev variables as a hash to the storeHours array
     because there won’t be another loop to compare it to.
   #}
  {% if loop.last %}
    {% set storeHours = storeHours|merge([{
      "days" : prevDays,
      "daysShort" : prevDaysShort,
      "open" : prevOpen,
      "close" : prevClose
    }]) %}
  {% endif %}

{% endfor %}

The storeHours data format will be something like this:
[
  {
    "days" : ["Monday", "Tuesday", "Wednesday"],
    "daysShort" : ["Mo","Tu","We"],
    "open" : "2017-01-21 09:30:00.000000",
    "close" : "2017-01-21 21:00:00.000000"
  },
  {
    "days" : ["Thursday","Friday"],
    "daysShort" : ["Th","Fr"],
    "open" : "2017-01-21 09:00:00.000000",
    "close" : "2017-01-21 17:00:00.000000"
  }
]

Once you've created your storeHours array, you can use it to output your HTML code.

  {% for item in storeHours %}

    
      {{ item.days|first }}{% if item.days|length > 1 %} - {{ item.days|last }}{% endif %}
        

    {% if item.open|length and item.close|length %}
      
        {{ item.open|date('h:i a') }} - {{ item.close|date('h:i a') }}
      
    {% else %}
      
        Closed
      
    {% endif %}

  {% endfor %}



BONUS ROUND: if you want to make Monday the first day of the week, reorder the days and daysShort arrays at the top like this:
{% set days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] %}
{% set daysShort = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'] %}

Then add this line just below it:
{% set hoursMondayFirst = entry.hoursOfOperation|slice(1,entry.hoursOfOperation|length)|merge(entry.hoursOfOperation|slice(0,1)) %}

That makes a new variable using Twig's slice filter to take Monday - Saturday (slice(1|length)) and merge Sunday at the end (slice(0,1)).
Now just use this as the start of your loop:
{% for item in hoursMondayFirst %}

> **Comments:**
> **username_0**: Will try this a little later. Agree it is a little complex.  

---

