Drupal 8: How to sort Datetime field base on time only?

14 Sep.2018
Drupal view - sort Datetime by time only

Working on one project for the KWALL company, we needed to sort the list of TV programs with different dates (repeated programs) by time ignoring the date (in your case, it could be a list of events). We didn't find, there is no way to do it with regular Drupal core methods. So we have created a custom views sort plugin.
In our case, the machine name for the DateTime field is "field_program_date".
I hope this shortcode will be useful to you.

File
modules/custom/program/program.module
/**
 * Implements hook_views_data_alter().
 */
function program_views_data_alter(array &$data) {
  $data['node__field_program_date']['field_program_date_time'] = array(
    'title' => t('Custom program sort'),
    'group' => t('Content'),
    'help' => t('Sort programs by time only.'),
    'sort' => array(
      'field' => 'field_program_date_value',
      'id' => 'program',
    ),
  );
}
File
modules/custom/program/src/Plugin/views/sort/Program.php
<?php
 
namespace Drupal\program\Plugin\views\sort;
 
use Drupal\views\Plugin\views\sort\Date;
 
/**
 * Basic sort handler for Programs.
 *
 * @ViewsSort("program")
 */
class Program extends Date {
 
  /**
   * Called to add the sort to a query.
   */
  public function query() {
    $this->ensureMyTable();
 
    $date_alias = "$this->tableAlias.$this->realField";
 
    // Maybe it's a bug in Drupal,
    // but for some reasons we need to add -7h offset from Phoenix.
    // Maybe on your case, need to remove CONVERT_TZ().
    $this->query->addOrderBy(NULL,
      "HOUR(CONVERT_TZ($date_alias,'+00:00','-07:00'))",
      $this->options['order'],
      'date_hour'
    );
    $this->query->addOrderBy(NULL,
      "MINUTE($date_alias)",
      $this->options['order'],
      'date_minute'
    );
  }
}

This code adds a "virtual" field in MySQL using the format: 01, 02, 03 where digits are hours and minutes and make sort by this field.