<p>For those interested, I found out you can tell Craft to search the database for the time part only with the mySQL command time() (<a href="https://craftcms.stackexchange.com/questions/6600/order-entries-by-custom-time-field">Order entries by custom time field</a>). For example:</p>

<pre><code>{% set shows = craft.entries({
  section: 'shows',
  relatedTo: day.id,
  order: "time(startTime)",
}) %}
</code></pre>

<p>However, this sorts based on the absolute DB time (GMT time), so I substituted a conversion command for startTime:</p>

<pre><code>{% set convertedStartTime = 'convert_tz(startTime,"+00:00","-06:00")' %}

{% set shows = craft.entries({
  section: 'shows',
  relatedTo: day.id,
  order: "time(#{convertedStartTime})",
}) %}
</code></pre>

<p>To my complete shock, this actually works. I could not find a similar way to search for the current show, so I first filtered entries by day, then ran a for-loop to find the current show (there's only ten shows or so per day):</p>

<pre><code>{% set todaysShows = craft.entries({
  section: 'shows',
  relatedTo: today,
}) %}

{% for show in todaysShows if not done %}
    {% set start = show.startTime | date_modify('now') %}
    {% set end = show.endTime | date_modify('now') %}

    {% if now &gt;= start and now &lt; end %}
        {% set nowPlaying = show %}
        {% set done = true %}
    {% endif %}

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

CC BY-SA 3.0
2017-12-27T23:03:49.587Z
2017-12-28T00:47:43.480Z
2017-12-28T00:47:43.480Z
Joshua
<p>If your <code>day</code> field is a relation field you should search for your related entries with </p>

<pre><code>{% set today = insertYourLogicToFetchTheCurrentDay %}
{# eg set todayName = "now"|date("l")#}
{# set today = craft.categories.title(todayName).first() #}
{% set showsToday = craft.entries.section('shows').relatedTo(today).find() %}
</code></pre>

<p>I don't really understand the second part of your question to be honest. </p>

<p>Is your <code>rightNow</code> a valid DateTime object? Normally I would do it like that</p>

<pre><code>{% set startDate = now|date('U')%}
{% set endDate = now|date('U') %}
{% set entries = craft.entries.section('shows').startTime('&gt;='~startDate).endDate('&lt;=' ~ endDate).find() %}
</code></pre>

<p><strong>Edit</strong></p>

<p>Okay: based on our comments this solution could work (at least from my test) but this is just an example what you could do: i did no performance tests and it looks a little bit ugly since I did the "fast" way not the "I'm using craft styles and craft macros to make everything look good". You would have to extend it.</p>

<ol>
<li>Go to <a href="https://pluginfactory.io/" rel="nofollow noreferrer">Pluginfactory</a> and fill out your fields. Turn on the light switch for <code>FieldTypes</code></li>
<li>Download the files and move it to your Craft Plugins folder. You Plugin name should have the same name like your folder in plugins. So when you name your Plugin <code>MyPlugin</code> your folder is <code>/craft/plugins/myplugin/</code></li>
<li><p>Go to the generated file <code>/fieldtypes</code> and overwrite these functions</p>

<pre><code>/**
 * Returns the input value as it should be saved to the database.
 *
 * @param mixed $value
 * @return mixed
 */
public function prepValueFromPost($value)
{
    return $value['hours'] . $value['minutes'];
}

/**
 * Prepares the field's value for use.
 *
 * @param mixed $value
 * @return mixed
 */
public function prepValue($value)
{
    if(empty($value)){
        return [
            'hours' =&gt; '00',
            'minutes'   =&gt; '00'
        ];
    }
    return [
        'hours' =&gt; substr($value, 0, 2),
        'minutes' =&gt; substr($value, 2, 4),
    ];
}
</code></pre></li>
<li><p>There will be a template in your <code>/templates/field/...twig</code> folder change the input to something like this... I know this looks awful... you should style it and implement some logic to preselect fields and such</p>

<pre><code>&lt;select name="{{ name ~ '[hours]' }}"&gt;
    &lt;option value="00"&gt;00&lt;/option&gt;
    &lt;option value="01"&gt;01&lt;/option&gt;
    &lt;option value="02"&gt;02&lt;/option&gt;
    &lt;option value="03"&gt;03&lt;/option&gt;
    &lt;option value="04"&gt;04&lt;/option&gt;
    &lt;!-- and so on --&gt;
&lt;/select&gt;
selected = {{ values.hours }}

&lt;select name="{{ name ~ '[minutes]' }}"&gt;
    &lt;option value="00"&gt;00&lt;/option&gt;
    &lt;option value="01"&gt;01&lt;/option&gt;
    &lt;option value="02"&gt;02&lt;/option&gt;
    &lt;option value="03"&gt;03&lt;/option&gt;
    &lt;option value="03"&gt;03&lt;/option&gt;
    &lt;!-- and so on --&gt;
&lt;/select&gt;
selected = {{ values.minutes }}
</code></pre></li>
<li><p>Change your two fields to the new field type. That way your db values will look like <code>0030</code> for 00:30 or <code>1340</code> for 13:40 you can now display the values in your frontend with</p>

<pre><code>{% for entry in craft.entries.section('shows') %}
    {{ entry.startTime.hours }}:{{ entry.startTime.minutes }}&lt;br&gt;
    {{ entry.enddate.hours }}:{{ entry.e.minutes }}&lt;br&gt;
    {% set startDate = entry.startTime.hours ~ entry.startTime.minutes %}
    {% set endDate = entry.endTime.hours ~ entry.endTime.minutes %}
    {% if startDate &gt;= 0430 and endDate &lt;= 1340   %}
        The show is between 04:30 and 13:40
    {% endif %}
{% endfor %}
</code></pre>

<p>Thus you can search via</p>

<pre><code>{% set now = "now"|date('H') ~ "now"|date('i') %}
{% set entries = craft.entries.section('shows').relatedTo(day).find({
    'startdate': '&gt;='~now,
    'enddate': '&lt;='~now
}) %}
</code></pre></li>
</ol>

CC BY-SA 3.0
2017-12-27T17:43:47.640Z
Yes, rightNow is a dateTime object formatted as locale time (i.e. 4:00 PM). To clarify, these shows are date agnostic, meaning they happen at the same time every week, for instance 4-5 PM every Wednesday. (I turned the day into own category is because it makes the craft.entries search process easier.) Unfortunately, if I query for entries using just the time part (4:00 PM), Craft filtering assumes a full date (today at 4 PM), which throws off both the current show and and the sorting. Is that making more sense?
Joshua
CC BY-SA 3.0
2017-12-27T17:59:27.810Z
Ah now I see. I'm not sure if there is a good way to achieve this only with twig. I would probably build my custom `Query` in PHP and use a custom field type and no `date` field since you don't need the date anyway. But this can take some time to achieve if you are new to Craft and my experience is: most people don't want to use php. Let me know whether I should provide some code or not
Robin Schambach
CC BY-SA 3.0
2017-12-27T18:09:55.287Z
Thanks Robin! That's what I was afraid of. I've not yet explored the dark ways of  PHP/custom plugin path yet because we push stuff out so quickly :P. I could do always do a regular number field and use military time, though that's less idiomatic from a client perspective. Appreciate your time!
Joshua
CC BY-SA 3.0
2017-12-27T19:20:15.023Z
Please check my edit. If you want to have only one select box for hours and minutes just remove the other select and input values like `0000, 0030, 0100` with the corresponding display values `00:00, 00:30, 01:00` and so on. You can inspect the Crafts html or use the macro to generate your inputs and make them look good
Robin Schambach
CC BY-SA 3.0
2017-12-27T22:50:28.350Z
Thanks so much Robin! I found out afterwards that we couldn't go with the military time option, but I did find a neat solution I thought I'd post. See below.
Joshua
CC BY-SA 3.0
2017-12-27T17:27:29.073Z
2017-12-27T19:15:07.577Z
2017-12-27T19:15:07.577Z
Robin Schambach
<p>I am trying to </p>

<ol>
<li>filter and sort show entries by what time they begin</li>
<li>display the current show</li>
</ol>

<p>I have two fields, <code>startTime</code>and <code>endTime</code>, and while Craft lets me display only the time part in the Control Panel, I can't filter entries in my template by the time part only.</p>

<p>Listing out entries:</p>

<pre><code>{% set shows = craft.entries({
    section: 'shows',
    order: 'startTime asc',
    day: 'sunday',
}) %}
</code></pre>

<p>Displaying the current show:</p>

<pre><code>{% set nowPlaying = craft.entries({
    section: 'shows',
    startTime: '&lt;= ' ~ rightNow | date('c'),
    endTime: '&gt;' ~ rightNow | date('c'),
    day: rightNow | date('l'),
}) %}
</code></pre>

<p>If I create all my show entries on the same day, filtering by the whole date is fine, but that's assuming</p>

<ol>
<li>the times are never changed (thus updating the date)</li>
<li>I don't care to know what show is currently playing (because a show will only show up if I created it today).</li>
</ol>

<p>I prefer not to reinvent the wheel by making a template-side sorting algorithm. Is there not a more elegant way to query just the time part in Craft filtering?</p>

CC BY-SA 3.0
2017-12-27T16:43:08.193Z
To clarify, `day` is a related category in the show entry.
Joshua
<entry><datetime><filtering>
Sort entries by time part only of DateTime object
# Sort entries by time part only of DateTime object

(Asked by: username_0 on 2017-12-27)

I am trying to 

filter and sort show entries by what time they begin
display the current show

I have two fields, startTimeand endTime, and while Craft lets me display only the time part in the Control Panel, I can't filter entries in my template by the time part only.
Listing out entries:
{% set shows = craft.entries({
    section: 'shows',
    order: 'startTime asc',
    day: 'sunday',
}) %}

Displaying the current show:
{% set nowPlaying = craft.entries({
    section: 'shows',
    startTime: '<= ' ~ rightNow | date('c'),
    endTime: '>' ~ rightNow | date('c'),
    day: rightNow | date('l'),
}) %}

If I create all my show entries on the same day, filtering by the whole date is fine, but that's assuming

the times are never changed (thus updating the date)
I don't care to know what show is currently playing (because a show will only show up if I created it today).

I prefer not to reinvent the wheel by making a template-side sorting algorithm. Is there not a more elegant way to query just the time part in Craft filtering?

**Tags:** entry, datetime, filtering

> **Comments:**
> **username_0**: To clarify, `day` is a related category in the show entry.  

---

## 2 answers

### Answer by username_0 on 2017-12-27. Score: 2

For those interested, I found out you can tell Craft to search the database for the time part only with the mySQL command time() (Order entries by custom time field). For example:
{% set shows = craft.entries({
  section: 'shows',
  relatedTo: day.id,
  order: "time(startTime)",
}) %}

However, this sorts based on the absolute DB time (GMT time), so I substituted a conversion command for startTime:
{% set convertedStartTime = 'convert_tz(startTime,"+00:00","-06:00")' %}

{% set shows = craft.entries({
  section: 'shows',
  relatedTo: day.id,
  order: "time(#{convertedStartTime})",
}) %}

To my complete shock, this actually works. I could not find a similar way to search for the current show, so I first filtered entries by day, then ran a for-loop to find the current show (there's only ten shows or so per day):
{% set todaysShows = craft.entries({
  section: 'shows',
  relatedTo: today,
}) %}

{% for show in todaysShows if not done %}
    {% set start = show.startTime | date_modify('now') %}
    {% set end = show.endTime | date_modify('now') %}

    {% if now >= start and now < end %}
        {% set nowPlaying = show %}
        {% set done = true %}
    {% endif %}

  {% endfor %}`


---

### Answer by username_1 on 2017-12-27. Score: 1

If your day field is a relation field you should search for your related entries with 
{% set today = insertYourLogicToFetchTheCurrentDay %}
{# eg set todayName = "now"|date("l")#}
{# set today = craft.categories.title(todayName).first() #}
{% set showsToday = craft.entries.section('shows').relatedTo(today).find() %}

I don't really understand the second part of your question to be honest. 
Is your rightNow a valid DateTime object? Normally I would do it like that
{% set startDate = now|date('U')%}
{% set endDate = now|date('U') %}
{% set entries = craft.entries.section('shows').startTime('>='~startDate).endDate('<=' ~ endDate).find() %}

Edit
Okay: based on our comments this solution could work (at least from my test) but this is just an example what you could do: i did no performance tests and it looks a little bit ugly since I did the "fast" way not the "I'm using craft styles and craft macros to make everything look good". You would have to extend it.

Go to Pluginfactory and fill out your fields. Turn on the light switch for FieldTypes
Download the files and move it to your Craft Plugins folder. You Plugin name should have the same name like your folder in plugins. So when you name your Plugin MyPlugin your folder is /craft/plugins/myplugin/
Go to the generated file /fieldtypes and overwrite these functions
/**
 * Returns the input value as it should be saved to the database.
 *
 * @param mixed $value
 * @return mixed
 */
public function prepValueFromPost($value)
{
    return $value['hours'] . $value['minutes'];
}

/**
 * Prepares the field's value for use.
 *
 * @param mixed $value
 * @return mixed
 */
public function prepValue($value)
{
    if(empty($value)){
        return [
            'hours' => '00',
            'minutes'   => '00'
        ];
    }
    return [
        'hours' => substr($value, 0, 2),
        'minutes' => substr($value, 2, 4),
    ];
}

There will be a template in your /templates/field/...twig folder change the input to something like this... I know this looks awful... you should style it and implement some logic to preselect fields and such

    00
    01
    02
    03
    04
    

selected = {{ values.hours }}


    00
    01
    02
    03
    03
    

selected = {{ values.minutes }}

Change your two fields to the new field type. That way your db values will look like 0030 for 00:30 or 1340 for 13:40 you can now display the values in your frontend with
{% for entry in craft.entries.section('shows') %}
    {{ entry.startTime.hours }}:{{ entry.startTime.minutes }}
    {{ entry.enddate.hours }}:{{ entry.e.minutes }}
    {% set startDate = entry.startTime.hours ~ entry.startTime.minutes %}
    {% set endDate = entry.endTime.hours ~ entry.endTime.minutes %}
    {% if startDate >= 0430 and endDate <= 1340   %}
        The show is between 04:30 and 13:40
    {% endif %}
{% endfor %}

Thus you can search via
{% set now = "now"|date('H') ~ "now"|date('i') %}
{% set entries = craft.entries.section('shows').relatedTo(day).find({
    'startdate': '>='~now,
    'enddate': '<='~now
}) %}

> **Comments:**
> **username_0**: Yes, rightNow is a dateTime object formatted as locale time (i.e. 4:00 PM). To clarify, these shows are date agnostic, meaning they happen at the same time every week, for instance 4-5 PM every Wednesday. (I turned the day into own category is because it makes the craft.entries search process easier.) Unfortunately, if I query for entries using just the time part (4:00 PM), Craft filtering assumes a full date (today at 4 PM), which throws off both the current show and and the sorting. Is that making more sense?  
> **username_1**: Ah now I see. I'm not sure if there is a good way to achieve this only with twig. I would probably build my custom `Query` in PHP and use a custom field type and no `date` field since you don't need the date anyway. But this can take some time to achieve if you are new to Craft and my experience is: most people don't want to use php. Let me know whether I should provide some code or not  
> **username_0**: Thanks Robin! That's what I was afraid of. I've not yet explored the dark ways of  PHP/custom plugin path yet because we push stuff out so quickly :P. I could do always do a regular number field and use military time, though that's less idiomatic from a client perspective. Appreciate your time!  
> **username_1**: Please check my edit. If you want to have only one select box for hours and minutes just remove the other select and input values like `0000, 0030, 0100` with the corresponding display values `00:00, 00:30, 01:00` and so on. You can inspect the Crafts html or use the macro to generate your inputs and make them look good  
> **username_0**: Thanks so much Robin! I found out afterwards that we couldn't go with the military time option, but I did find a neat solution I thought I'd post. See below.  

---

