<p>You could use the <a href="https://github.com/aelvan/Preparse-Field-Craft" rel="nofollow noreferrer">Preparse</a> plugin to store the actual date of the event into a dedicated field (hidden in the CP). So for example store <em>2018-02-20 02:00</em> for an event with a <code>whatDateAreTheyPerforming</code> date set to <em>2018-02-19</em>. Then use the Preparse field’s value for sorting within your groups.</p>

<p>This code should work to compute the date string with Preparse:</p>

<pre><code>{% set actualDate = entry.whatDateAreTheyPerforming|date('Y-m-d')
    ~ entry.startTime|date(' H:i:s') %}

{%- set isTomorrow = actualDate|date('G') &lt; 5 %}
{%- set actualDate = isTomorrow ? actualDate|date_modify('+1 day') : actualDate %}

{{- actualDate|date('Y-m-d H:i:s') }}
</code></pre>

<p>If you don’t want to use Preparse, another simple approach would be to simply loop twice:</p>

<pre><code>{# Output events after 05:00 #}
{% for entry in entries if entry.startTime|date('G') &gt;= 5 %}
{% endfor %}

{# Output events before 05:00 #}
{% for entry in entries if entry.startTime|date('G') &lt; 5 %}
{% endfor %}
</code></pre>

CC BY-SA 3.0
2018-02-21T04:05:50.377Z
I ended up looping twice in the end, the code I had is very similar to yours conceptually. I also didn't realise that you could put conditionals straight in the `{{ for }}` loop so thanks for pointing that out!
MikeeBee
CC BY-SA 3.0
2018-02-21T06:23:31.760Z
I'd actually recommend the Preparse approach, have the real date stored somewhere.
carlcs
CC BY-SA 3.0
2018-02-21T21:59:48.807Z
I'm not sure I fully understand how Preparse works actually. So I would need to create a seperate date field? Would the user need to add 2 dates?
 
There are a lot of entries that would need updating to include this new field, unless I'm misunderstanding?
MikeeBee
CC BY-SA 3.0
2018-02-22T11:11:00.780Z
Yeah, it would be a separate field, but one that populates automatically and there’s a setting to hide it so the user wont even notice it exists. Populate it for existing entries by re-saving the section’s settings. I’ll update the answer with the Twig code that would go into the Preparse field.
carlcs
CC BY-SA 3.0
2018-02-19T15:03:40.927Z
2018-02-22T11:17:45.450Z
2018-02-22T11:17:45.450Z
carlcs
<p>Thanks for the answers! I ended up using the advice found in this article that I have found to be endlessly useful - <a href="https://www.webstoemp.com/blog/manipulating-craft-elementcriteriamodel-with-twig/" rel="nofollow noreferrer">Manipulating Craft's ElementCriteriaModel objects with Twig</a>.</p>

<p>Gathering an array of ids of entries that pass the conditional, as well as another array of ones that don't. Then outputting them separately which allowed me to tweak the time order to <code>time(startTime) asc</code> in the <code>postMidnight</code> entries.</p>

<pre><code>{% set entryIds = craft.entries.section('lineUp').ids() %}
{% set categories = craft.categories.relatedTo({ sourceElement: entryIds }).find() %}

{% for category in categories %}

  {# Fetch all of the entries related to this category #}
  {% set entries = craft.entries.relatedTo(category) %}

    {# Group entries by date and order by start time #}
    {% for date, entries in entries.order('whatDateAreTheyPerforming', 'time(startTime) desc')|
  group('whatDateAreTheyPerforming') %}
        &lt;div&gt;

            &lt;h3&gt;{{ date | date('l') }} &lt;span&gt;{{ date | date('jS') }}&lt;/span&gt;&lt;/h3&gt;

            {# Arrays to store the IDs of the entries as we find them #}
            {% set postMidnightIDs = [] %}
            {% set preMidnightIDs = [] %}

            &lt;ul&gt;

                {% for entry in entries %}
                    {% if entry.startTime &gt;= entry.startTime|date_modify('00:00') and entry.endTime &lt;= entry.endTime|date_modify('05:00') %}
                       {% set postMidnightIDs = postMidnightIDs|merge([entry.id]) %}
                       {# Or of course you could output the data here but I like to keep building and output separately for clarity #}
                   {% else %}
                       {% set preMidnightIDs = preMidnightIDs|merge([entry.id])  %}
                   {% endif %}
                {% endfor %}

                {% set postMidnightIDsString = postMidnightIDs|join(', ') %}
                {% set preMidnightIDsString = preMidnightIDs|join(', ')  %}

                {# Entries that appear between midnight and 5am #}
                {% for entry in craft.entries.section('lineUp').id(postMidnightIDsString).order('time(startTime) asc').find() %}

                    {# Created a macro to avoid code duplication #}
                    {{ macros.lineUpItem(entry.artistLogo, entry.title, entry.url, entry.whatDateAreTheyPerforming, entry.startTime, entry.endTime, entry.sponsor) }}

                {% endfor %}

                {# Entries that appear between 5am and midnight #}
                {% for entry in craft.entries.section('lineUp').id(preMidnightIDsString).order('time(startTime) desc').find() %}

                    {{ macros.lineUpItem(entry.artistLogo, entry.title, entry.url, entry.whatDateAreTheyPerforming, entry.startTime, entry.endTime, entry.sponsor) }}

                {% endfor %}

            &lt;/ul&gt;
        &lt;/div&gt;&lt;!-- col --&gt;
    {% endfor %} 

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

CC BY-SA 3.0
2018-02-21T04:00:24.120Z
2018-02-21T05:20:36.543Z
2018-02-21T05:20:36.543Z
MikeeBee
<p>I -think- one of the neatest ways to go about this is to introduce a "Show as last in list" lightswitch-field.</p>

<p>I'm currently working on a similar project (festival line-up) where I also needed this; here's the approach I went with.</p>

<p>Basically, I'll be going for two fields: <code>eventTime</code> (date/time-field) and <code>showAsLastInList</code> (lightswitch-field)</p>

<pre><code>{% set events = craft.entries.section('events').showAsLastInList('NOT 1').orderBy('eventTime ASC').all %}

{% for date, eventsByDate in events|group('eventTime|date("Y-m-d")') %}
    {% set additionalEvents = craft.entries.section('events').eventTime(date).showAsLastInList('1').orderBy('eventTime ASC').all %}
    &lt;div class="program__dateline" data-filter-dateline&gt;{{ date|date('l j. F')|capitalize }}&lt;/div&gt;
    {% for event in eventsByDate|merge(additionalEvents) %}
       {# PRINT YOUR HTML HERE #}
    {% endfor %}
{% endfor %}
</code></pre>

<p>It's not exactly pretty, but I can't really think of another way to achieve this without creating a custom plugin for it.</p>

CC BY-SA 3.0
2018-02-21T04:03:02.840Z
I like the simplicity of this! I think the only downside is that it requires user input, but an upside is that it gives them a little more control. Thanks for the suggestion :)
MikeeBee
CC BY-SA 3.0
2018-02-19T09:23:00.607Z
2018-02-19T09:45:15.357Z
2018-02-19T09:45:15.357Z
Fuglsetrampen
<p>I'm creating a line up listing page for a festival, across 4 nights. Acts are listed, per day, sorted by a <code>date</code> field in order of a start <code>time</code> field.</p>

<p>The issue I'm having is that midnight until 3am is still considered the night of an event but my <code>time</code> field obviously considers it otherwise.</p>

<p>e.g. an act is performing on the Friday morning at 1am but I need to list this at the <em>end</em> of the Thursday acts.</p>

<p>So the user adds it to the CMS on the Thursday but it appears at the start of the day instead of the end.</p>

<p>Essentially, I just need any acts that appear between <code>00:00</code> and <code>03:00</code> at the top of a list e.g</p>

<h3>Thursday</h3>

<ul>
<li><strong>Act 1</strong> - 1am - 2am</li>
<li><strong>Act 2</strong> - 12am - 1am</li>
<li><strong>Act 3</strong> - 11pm - 12am</li>
<li><strong>Act 4</strong> - 10pm - 11pm</li>
</ul>

<p>etc</p>

<h2>This is the code I have so far</h2>

<p><code>whatDateAreTheyPerforming</code> is a date field</p>

<p><code>startTime</code> and <code>endTime</code> are time fields</p>

<pre><code>{% set entryIds = craft.entries.section('lineUp').ids() %}
{% set categories = craft.categories.relatedTo({ sourceElement: entryIds }).find() %}

{% for category in categories %}

  {# Fetch all of the entries related to this category #}
  {% set entries = craft.entries.relatedTo(category) %}

  {# Group entries by date and order by start time #}
  {% for date, entries in entries.order('whatDateAreTheyPerforming', 'time(startTime) desc')|
  group('whatDateAreTheyPerforming') %}
    &lt;div&gt;

      &lt;h3&gt;DAY HERE - {{ date | date('l') }} &lt;span&gt;{{ date | date('jS') }}&lt;/span&gt;&lt;/h3&gt;

      &lt;ul&gt;

        {% for entry in entries %}

        &lt;li&gt;
          &lt;h4&gt;{{ entry.title }} 
              &lt;span&gt;{{ entry.whatDateAreTheyPerforming | date('l') }} - {{ entry.startTime | date('G:i') }} - {{ entry.endTime | date('G:i') }}&lt;/span&gt;
          &lt;/h4&gt;
        &lt;/li&gt;

        {% endfor %}

      &lt;/ul&gt;
    &lt;/div&gt;&lt;!-- col --&gt;
  {% endfor %} 

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

<p>I hope this makes sense, any guidance will be appreciated. </p>

<ordering><order>
Show time ordered entries from midnight at end of loop
# Show time ordered entries from midnight at end of loop

(Asked by: username_0 on 2018-02-17)

I'm creating a line up listing page for a festival, across 4 nights. Acts are listed, per day, sorted by a date field in order of a start time field.
The issue I'm having is that midnight until 3am is still considered the night of an event but my time field obviously considers it otherwise.
e.g. an act is performing on the Friday morning at 1am but I need to list this at the end of the Thursday acts.
So the user adds it to the CMS on the Thursday but it appears at the start of the day instead of the end.
Essentially, I just need any acts that appear between 00:00 and 03:00 at the top of a list e.g
Thursday

Act 1 - 1am - 2am
Act 2 - 12am - 1am
Act 3 - 11pm - 12am
Act 4 - 10pm - 11pm

etc
This is the code I have so far
whatDateAreTheyPerforming is a date field
startTime and endTime are time fields
{% set entryIds = craft.entries.section('lineUp').ids() %}
{% set categories = craft.categories.relatedTo({ sourceElement: entryIds }).find() %}

{% for category in categories %}

  {# Fetch all of the entries related to this category #}
  {% set entries = craft.entries.relatedTo(category) %}

  {# Group entries by date and order by start time #}
  {% for date, entries in entries.order('whatDateAreTheyPerforming', 'time(startTime) desc')|
  group('whatDateAreTheyPerforming') %}
    

      DAY HERE - {{ date | date('l') }} {{ date | date('jS') }}

      

        {% for entry in entries %}

        
          {{ entry.title }} 
              {{ entry.whatDateAreTheyPerforming | date('l') }} - {{ entry.startTime | date('G:i') }} - {{ entry.endTime | date('G:i') }}
          
        

        {% endfor %}

      
    
  {% endfor %} 

{% endfor %}

I hope this makes sense, any guidance will be appreciated.

**Tags:** ordering, order


---

## 3 answers

### Answer by username_1 on 2018-02-19. Score: 1

You could use the Preparse plugin to store the actual date of the event into a dedicated field (hidden in the CP). So for example store 2018-02-20 02:00 for an event with a whatDateAreTheyPerforming date set to 2018-02-19. Then use the Preparse field’s value for sorting within your groups.
This code should work to compute the date string with Preparse:
{% set actualDate = entry.whatDateAreTheyPerforming|date('Y-m-d')
    ~ entry.startTime|date(' H:i:s') %}

{%- set isTomorrow = actualDate|date('G') < 5 %}
{%- set actualDate = isTomorrow ? actualDate|date_modify('+1 day') : actualDate %}

{{- actualDate|date('Y-m-d H:i:s') }}

If you don’t want to use Preparse, another simple approach would be to simply loop twice:
{# Output events after 05:00 #}
{% for entry in entries if entry.startTime|date('G') >= 5 %}
{% endfor %}

{# Output events before 05:00 #}
{% for entry in entries if entry.startTime|date('G') < 5 %}
{% endfor %}

> **Comments:**
> **username_0**: I ended up looping twice in the end, the code I had is very similar to yours conceptually. I also didn't realise that you could put conditionals straight in the `{{ for }}` loop so thanks for pointing that out!  
> **username_1**: I'd actually recommend the Preparse approach, have the real date stored somewhere.  
> **username_0**: I'm not sure I fully understand how Preparse works actually. So I would need to create a seperate date field? Would the user need to add 2 dates?   There are a lot of entries that would need updating to include this new field, unless I'm misunderstanding?  
> **username_1**: Yeah, it would be a separate field, but one that populates automatically and there’s a setting to hide it so the user wont even notice it exists. Populate it for existing entries by re-saving the section’s settings. I’ll update the answer with the Twig code that would go into the Preparse field.  

---

### Answer by username_0 on 2018-02-21. Score: 1

Thanks for the answers! I ended up using the advice found in this article that I have found to be endlessly useful - Manipulating Craft's ElementCriteriaModel objects with Twig.
Gathering an array of ids of entries that pass the conditional, as well as another array of ones that don't. Then outputting them separately which allowed me to tweak the time order to time(startTime) asc in the postMidnight entries.
{% set entryIds = craft.entries.section('lineUp').ids() %}
{% set categories = craft.categories.relatedTo({ sourceElement: entryIds }).find() %}

{% for category in categories %}

  {# Fetch all of the entries related to this category #}
  {% set entries = craft.entries.relatedTo(category) %}

    {# Group entries by date and order by start time #}
    {% for date, entries in entries.order('whatDateAreTheyPerforming', 'time(startTime) desc')|
  group('whatDateAreTheyPerforming') %}
        

            {{ date | date('l') }} {{ date | date('jS') }}

            {# Arrays to store the IDs of the entries as we find them #}
            {% set postMidnightIDs = [] %}
            {% set preMidnightIDs = [] %}

            

                {% for entry in entries %}
                    {% if entry.startTime >= entry.startTime|date_modify('00:00') and entry.endTime <= entry.endTime|date_modify('05:00') %}
                       {% set postMidnightIDs = postMidnightIDs|merge([entry.id]) %}
                       {# Or of course you could output the data here but I like to keep building and output separately for clarity #}
                   {% else %}
                       {% set preMidnightIDs = preMidnightIDs|merge([entry.id])  %}
                   {% endif %}
                {% endfor %}

                {% set postMidnightIDsString = postMidnightIDs|join(', ') %}
                {% set preMidnightIDsString = preMidnightIDs|join(', ')  %}

                {# Entries that appear between midnight and 5am #}
                {% for entry in craft.entries.section('lineUp').id(postMidnightIDsString).order('time(startTime) asc').find() %}

                    {# Created a macro to avoid code duplication #}
                    {{ macros.lineUpItem(entry.artistLogo, entry.title, entry.url, entry.whatDateAreTheyPerforming, entry.startTime, entry.endTime, entry.sponsor) }}

                {% endfor %}

                {# Entries that appear between 5am and midnight #}
                {% for entry in craft.entries.section('lineUp').id(preMidnightIDsString).order('time(startTime) desc').find() %}

                    {{ macros.lineUpItem(entry.artistLogo, entry.title, entry.url, entry.whatDateAreTheyPerforming, entry.startTime, entry.endTime, entry.sponsor) }}

                {% endfor %}

            
        
    {% endfor %} 

{% endfor %}


---

### Answer by username_2 on 2018-02-19. Score: 1

I -think- one of the neatest ways to go about this is to introduce a "Show as last in list" lightswitch-field.
I'm currently working on a similar project (festival line-up) where I also needed this; here's the approach I went with.
Basically, I'll be going for two fields: eventTime (date/time-field) and showAsLastInList (lightswitch-field)
{% set events = craft.entries.section('events').showAsLastInList('NOT 1').orderBy('eventTime ASC').all %}

{% for date, eventsByDate in events|group('eventTime|date("Y-m-d")') %}
    {% set additionalEvents = craft.entries.section('events').eventTime(date).showAsLastInList('1').orderBy('eventTime ASC').all %}
    {{ date|date('l j. F')|capitalize }}
    {% for event in eventsByDate|merge(additionalEvents) %}
       {# PRINT YOUR HTML HERE #}
    {% endfor %}
{% endfor %}

It's not exactly pretty, but I can't really think of another way to achieve this without creating a custom plugin for it.

> **Comments:**
> **username_0**: I like the simplicity of this! I think the only downside is that it requires user input, but an upside is that it gives them a little more control. Thanks for the suggestion :)  

---

