Angular Time Picker Component

Time Picker

CoreUI PRO
This component is part of CoreUI PRO – a powerful UI library with over 250 components and 25+ templates, designed to help you build modern, responsive apps faster. Fully compatible with Angular, Bootstrap, React.js, and Vue.js.

Create consistent cross-browser and cross-device Angular time picker.

Available in Other JavaScript Frameworks

CoreUI Angular Time Picker Component is also available for Bootstrap, React, and Vue. Explore framework-specific implementations below:

Examples

import { Component } from '@angular/core';
import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-example',
  templateUrl: './time-picker-example.component.html',
  standalone: true,
  imports: [RowComponent, ColComponent, TimePickerComponent]
})
export class TimePickerExampleComponent {
  time? = new Date();
}
<c-row>
  <c-col lg="4">
    <c-time-picker />
  </c-col>

  <c-col lg="4">
    <c-time-picker [time]="time" />
  </c-col>
</c-row>

Sizing

Set heights using size property like size="lg" and size="sm".

import { Component } from '@angular/core';
import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-sizing',
  templateUrl: './time-picker-sizing.component.html',
  imports: [RowComponent, ColComponent, TimePickerComponent]
})
export class TimePickerSizingComponent {}
<c-row class="mb-4">
  <c-col lg="5">
    <c-time-picker size="lg" />
  </c-col>
</c-row>

<c-row>
  <c-col lg="4">
    <c-time-picker size="sm" />
  </c-col>
</c-row>

Disabled

Add the disabled boolean attribute on an input to give it a grayed out appearance and remove pointer events. Disabling the picker also closes its open menu.

import { Component } from '@angular/core';
import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-disabled',
  templateUrl: './time-picker-disabled.component.html',
  imports: [RowComponent, ColComponent, TimePickerComponent]
})
export class TimePickerDisabledComponent {
  time? = new Date();
}
<c-row>
  <c-col lg="4">
    <c-time-picker disabled />
  </c-col>

  <c-col lg="4">
    <c-time-picker disabled [time]="time" />
  </c-col>
</c-row>

Typing a time

The input reads a time typed the way the picker shows it in its locale, with the locale’s digits and day periods (9:05 PM, 오후 9:05, ۲۱:۰۵), as well as 24-hour time (21:05), a dot as the separator (21.05) and AM/PM in any letter case. A time without a day period is read as 24-hour time. The time is read when the input changes (Enter or leaving the input) and on ArrowDown or Alt + ArrowDown, each part snaps to the nearest value allowed by its filter, and seconds are kept only with seconds. Text that is not a time clears the picker. Picking a value in the menu before the typed text is read replaces that text with the picked time.

A string bound to time or written by a form control is read the same way, along with ISO times and date-times (15:30:00, 2026-01-05T15:30:00, 2026-01-05 15:30:00). A string in the locale’s own format is read with the picker’s locale, also when the locale arrives later; a time already read, picked or cleared stays when only locale changes.

The picker reports a Date. A time without a date, from a time string or picked or typed into an empty picker, is set on 1 January 1970; a time string with a UTC offset (15:30Z, 15:30+02:00) is that moment on 1 January 1970, so its local date can be a day earlier or later. A picked or typed time keeps the date of the time it replaces. A Date bound to time or written by a form control keeps its moment, also when it comes from another window or frame, and so does a date-time string (2026-01-05T15:30:00). To store or send a time without a date, use its hours, minutes and, with seconds, seconds rather than toISOString(): the UTC offset of 1 January 1970 can differ from today’s.

Readonly

Add the inputReadOnly boolean attribute to prevent modification of the input value.

import { Component } from '@angular/core';
import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-readonly',
  templateUrl: './time-picker-readonly.component.html',
  imports: [RowComponent, ColComponent, TimePickerComponent]
})
export class TimePickerReadonlyComponent {}
<c-row>
  <c-col lg="4">
    <c-time-picker inputReadOnly />
  </c-col>
</c-row>

Validation

Set valid to show the validation state. [valid]="false" also sets aria-invalid="true" on the input or, in the select variant, on every select. aria-describedby on c-time-picker, as a static attribute or bound with [aria-describedby], moves to the same fields, so the feedback is read with them; [attr.aria-describedby] does not reach the fields.

import { Component } from '@angular/core';
import { ColComponent, FormFeedbackComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-validation',
  templateUrl: './time-picker-validation.component.html',
  imports: [ColComponent, FormFeedbackComponent, RowComponent, TimePickerComponent]
})
export class TimePickerValidationComponent {}
<c-row>
  <c-col lg="4">
    <c-time-picker [valid]="false" aria-describedby="timePickerFeedback" />
    <c-form-feedback id="timePickerFeedback" [valid]="false">Choose a time.</c-form-feedback>
  </c-col>
</c-row>

Filtered

Add filter callback functions to limit selectable values. The first choice in an empty picker fills the parts not picked yet with their first allowed values (seconds stay 0 without seconds), so it reports one time. In a 12-hour locale an empty picker shows the day period of the first allowed hour, a day period without allowed hours is disabled, and switching the day period keeps the hour 12 hours apart when it is allowed, otherwise it takes the first allowed hour of that day period.

import { DatePipe } from '@angular/common';
import { Component, signal } from '@angular/core';
import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-filtered',
  templateUrl: './time-picker-filtered.component.html',
  imports: [RowComponent, ColComponent, TimePickerComponent, DatePipe]
})
export class TimePickerFilteredComponent {
  filterHours = (hour: number): boolean => hour > 8 && hour <= 23;
  filterMinutes = (min: number): boolean => (min %= 10) === 0;
  filterSeconds = (sec: number): boolean => (sec %= 15) === 0;

  readonly time = signal<Date | undefined>(new Date(1970, 0, 1, 14, 30, 15));

  handleTimeChange(time: Date | undefined) {
    if (time) {
      this.time.set(new Date(time?.getTime()));
    } else {
      this.time.set(time);
    }
  }
}
<c-row>
  <c-col lg="4">
    <c-time-picker
      (timeChange)="handleTimeChange($event)"
      [filterHours]="filterHours"
      [filterMinutes]="filterMinutes"
      [filterSeconds]="filterSeconds"
      [(time)]="time"
      seconds
    />
  </c-col>
  <c-col class="d-flex align-items-center">
    {{time() | date:'shortTime'}}
  </c-col>
</c-row>
import { Component, signal } from '@angular/core';
import {
  ButtonDirective,
  ColComponent,
  DropdownCloseDirective,
  RowComponent,
  TemplateIdDirective,
  TimePickerComponent
} from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-with-footer',
  templateUrl: './time-picker-with-footer.component.html',
  imports: [
    RowComponent,
    ColComponent,
    TimePickerComponent,
    TemplateIdDirective,
    ButtonDirective,
    DropdownCloseDirective
  ]
})
export class TimePickerWithFooterComponent {
  readonly time = signal(new Date());
}
<c-row>
  <c-col lg="4">
    <c-time-picker
      [(time)]="time"
      placeholder="-- : --"
      #timePicker="cTimePicker"
    >
      <ng-template cTemplateId="timePickerFooter" let-dropdown>
        <button cButton color="secondary" variant="ghost" size="sm"
                (click)="timePicker.clearTime()" cDropdownClose
                [dropdownComponent]="dropdown">
          Cancel
        </button>
        <button cButton color="primary" size="sm" [disabled]="!time()" cDropdownClose [dropdownComponent]="dropdown">OK</button>
      </ng-template>
    </c-time-picker>
  </c-col>
</c-row>

Non-english locale

Auto

import { Component } from '@angular/core';
import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-auto',
  templateUrl: './time-picker-auto.component.html',
  imports: [RowComponent, ColComponent, TimePickerComponent]
})
export class TimePickerAutoComponent {}
<c-row>
  <c-col lg="4">
    <c-time-picker />
  </c-col>
</c-row>

Chinese

import { Component } from '@angular/core';
import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-chinese',
  templateUrl: './time-picker-chinese.component.html',
  imports: [RowComponent, ColComponent, TimePickerComponent]
})
export class TimePickerChineseComponent {}
<c-row>
  <c-col lg="4">
    <c-time-picker placeholder="入住日期" locale="zh-CN" seconds />
  </c-col>
</c-row>

Japanese

import { Component } from '@angular/core';
import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-japanese',
  templateUrl: './time-picker-japanese.component.html',
  imports: [RowComponent, ColComponent, TimePickerComponent]
})
export class TimePickerJapaneseComponent {}
<c-row>
  <c-col lg="4">
    <c-time-picker placeholder="日付を選択" locale="ja" seconds />
  </c-col>
</c-row>

Korean

import { Component } from '@angular/core';
import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-korean',
  templateUrl: './time-picker-korean.component.html',
  imports: [RowComponent, ColComponent, TimePickerComponent]
})
export class TimePickerKoreanComponent {}
<c-row>
  <c-col lg="4">
    <c-time-picker placeholder="날짜 선택" locale="ko" />
  </c-col>
</c-row>

Hebrew

import { Component } from '@angular/core';
import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-hebrew',
  templateUrl: './time-picker-hebrew.component.html',
  imports: [RowComponent, ColComponent, TimePickerComponent]
})
export class TimePickerHebrewComponent {}
<c-row>
  <c-col lg="4">
    <c-time-picker placeholder="בחר תאריך" locale="he-IL" />
  </c-col>
</c-row>

Persian

import { Component } from '@angular/core';
import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-persian',
  templateUrl: './time-picker-persian.component.html',
  imports: [RowComponent, ColComponent, TimePickerComponent]
})
export class TimePickerPersianComponent {}
<c-row>
  <c-col lg="4">
    <c-time-picker placeholder="تاریخ شروع" locale="fa-IR" seconds />
  </c-col>
</c-row>

Accessibility

  • The input is a combobox that opens a dialog with the time selection: it has aria-haspopup="dialog", aria-expanded, and aria-controls pointing to the open menu, named by ariaPopupLabel (Time selection). Added in v5.7.41
  • The roll columns are named by ariaSelectHoursLabel, ariaSelectMinutesLabel, ariaSelectSecondsLabel and ariaSelectMeridiemLabel (Select hours, Select minutes, Select seconds, Select AM/PM), and their values are options with aria-selected, named with the value and the column name (07, Select hours), so a screen reader says the unit when the focus moves between columns. The selects of the select variant get the same names, which take the place of a <label> wrapping the picker, so a picker with a visible label needs that label in these names, e.g. ariaSelectHoursLabel="Start time, hours". Added in v5.7.41
  • On a right-to-left page the columns read AM/PM, hours, minutes, seconds from the left, the way the time is written, and the arrow keys follow that order. Added in v5.7.41
  • Closing the menu after using it (Escape, a button in the footer, a click outside) returns focus to the input. After a tap or a pen press in the menu an editable input does not get it back; a read-only input (inputReadOnly) does.

Keyboard behavior

KeyAction
ArrowDown or Alt + ArrowDown (Option on macOS) in the inputRead the typed text as leaving the input does, open the menu and move focus to the selected hour, or the first hour when none is selected Added in v5.7.41
Tab / Shift + TabMove between the input and the columns, landing on each column’s selected value, or its first value when none is selected; a time typed in the input is read first; tabbing out of the picker closes the menu
ArrowDown / ArrowUp on a valueMove to the next or previous value in the column
Home / End on a valueMove to the first or last value in the column Added in v5.7.41
ArrowLeft / ArrowRight on a valueMove to the column on that side Added in v5.7.41
Enter / Space on a valuePick it. Then the focus moves to the next column in the order hours, minutes, seconds, AM/PM, and stays in the last one Added in v5.7.41
EscapeClose the menu, focus the input

Forms

Angular handles user input through reactive and template-driven forms. CoreUI Time Picker supports both types.

The picker updates its form control and emits timeChange once when the user changes the time or the page calls clearTime(). With the default updateOn: 'change', a correction made in valueChanges is kept and is the time timeChange carries. Binding time or writing the form control updates the picker without either. A bound or written time that the filters or seconds do not allow is shown at the nearest allowed value, while the binding and the form keep the value they set until the user picks a time.

Reactive

import { JsonPipe } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';

import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

interface ITimePickerForm {
  timePicker: FormControl<Date | undefined | null>;
}

@Component({
  selector: 'docs-time-picker-reactive',
  templateUrl: './time-picker-reactive.component.html',
  imports: [RowComponent, ColComponent, ReactiveFormsModule, TimePickerComponent, JsonPipe]
})
export class TimePickerReactiveComponent implements OnInit {
  time = new Date();

  formGroup!: FormGroup<ITimePickerForm>;

  get toLocaleTimeString() {
    return this.formGroup.value.timePicker ? this.formGroup.value.timePicker.toLocaleTimeString() : '';
  }

  ngOnInit(): void {
    this.time.setMilliseconds(0);
    this.time.setSeconds(0);
    this.time.setMinutes(15);
    this.time.setHours(11);

    this.formGroup = new FormGroup<ITimePickerForm>({
      timePicker: new FormControl(this.time, { nonNullable: false })
    });
  }
}
<c-row>
  <c-col lg="4">
    <form [formGroup]="formGroup">
      <c-time-picker formControlName="timePicker" seconds />
    </form>
  </c-col>
</c-row>
<br>
Form value: {{formGroup.value | json }}
<br>
timePicker value: {{toLocaleTimeString}}

Template-driven

import { DatePipe, JsonPipe } from '@angular/common';
import { Component, OnInit, signal } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import { ColComponent, RowComponent, TimePickerComponent } from '@coreui/angular';

@Component({
  selector: 'docs-time-picker-template-driven',
  templateUrl: './time-picker-template-driven.component.html',
  imports: [RowComponent, ColComponent, ReactiveFormsModule, FormsModule, TimePickerComponent, JsonPipe, DatePipe]
})
export class TimePickerTemplateDrivenComponent implements OnInit {
  readonly time = signal(new Date());

  ngOnInit(): void {
    const time = this.time();
    time.setMilliseconds(0);
    time.setSeconds(0);
    time.setMinutes(15);
    time.setHours(13);
    this.time.set(time);
  }
}
<c-row>
  <c-col lg="4">
    <form #form="ngForm">
      <c-time-picker [(ngModel)]="time" name="timePicker" />
    </form>
  </c-col>
</c-row>
<br>
Form value: {{ form.value | json }}
<br>
timePicker value: {{ form.value['timePicker'] | date:'H:mm'}}

API reference

TimePicker Module

import { 
  TimePickerModule,
  DropdownModule,
  SharedModule
} from '@coreui/angular';

@NgModule({
    imports: [
      TimePickerModule,
      DropdownModule,
      SharedModule
    ]
})
export class AppModule() { }

c-time-picker

component

jsx
import { TimePickerComponent } from '@coreui/angular-pro'

Props

PropertyDefaultType
aria-describedby5.7.40+undefinedstring, null

Ids of the elements that describe the field, e.g. a hint or the validation message; set on the input or, in the select variant, on every select. A validation message hidden by CSS is still read, so bind its id only while the field is invalid: [aria-describedby]="invalid ? 'feedback' : null". Set it as a static attribute, which is removed from the host, or bind [aria-describedby]; [attr.aria-describedby] does not reach the field.

ariaPopupLabel5.7.41+'Time selection'string

Accessible name of the menu with the time selection.

ariaSelectHoursLabel5.7.41+'Select hours'string

Accessible name of the hours column in the roll and of the hours select; each value in the column is named with the value and this text, e.g. 07, Select hours.

ariaSelectMeridiemLabel5.7.41+'Select AM/PM'string

Accessible name of the AM/PM column in the roll and of the AM/PM select; each value in the column is named with the value and this text, e.g. AM, Select AM/PM.

ariaSelectMinutesLabel5.7.41+'Select minutes'string

Accessible name of the minutes column in the roll and of the minutes select; each value in the column is named with the value and this text, e.g. 05, Select minutes.

ariaSelectSecondsLabel5.7.41+'Select seconds'string

Accessible name of the seconds column in the roll and of the seconds select; each value in the column is named with the value and this text, e.g. 30, Select seconds.

cleanertrueboolean

Toggle visibility or set the content of the cleaner button.

dateTimeFormatOptions{}DateTimeFormatOptions

Sets DateTime format options including timeZone

disabledfalseboolean

Toggle the disabled state for the component.

filterHoursundefinedobject

Filter available hours to pick.

filterMinutesundefinedobject

Filter available minutes to pick.

filterSecondsundefinedobject

Filter available seconds to pick.

indicatortrueboolean

Toggle visibility or set the content of the input indicator.

inputReadOnlyfalseboolean

Toggle the readonly state for the component.

locale'default'string

Sets the default locale for components. If not set, it is inherited from the browser.

placeholder'Select time'string

Specifies a short hint visible in time input.

secondsfalseboolean

Toggle seconds visibility.

sizeundefined'', 'sm', 'lg'

Size the component small or large.

timeundefinedstring, Date

Initially selected time. A change updates the picker without emitting timeChange or reaching the form control.

validundefinedboolean

Validation state: true valid, false invalid, which also sets aria-invalid="true" on the input or, in the select variant, on every select, undefined none.

variant'roll''roll', 'select'

Set the time picker variant to a roll or select.

visiblefalseboolean

Toggle the visibility of dropdown timepicker menu component.

Events

Event name
timeChange

Event emitted when the user changes the time or the page calls clearTime(), with the time the picker holds after the form control handled the change; the time input and form writes do not emit.

  • $event Date | undefined