Skip to main content

Overview

The DateTimePicker component combines date and time selection in a single, user-friendly interface. It includes a Material Design calendar picker and optional clock picker for time selection, with support for custom date/time formats.

When to Use

Use the DateTimePicker component when you need to:
  • Schedule appointments or meetings (date + specific time)
  • Set deadlines with precise timing
  • Create events that require both date and time
  • Provide a unified interface for datetime selection
For date only, use DatePicker. For time only, use TimePicker.

Basic Usage

import { DateTimePicker } from 'mat-dynamic-form';

const appointmentPicker = new DateTimePicker(
  'appointment',
  'Appointment'
);

Common Patterns

DateTime Picker with Custom Format

import { Validators } from '@angular/forms';

const meetingPicker = new DateTimePicker(
  'meeting',
  'Meeting Time',
  new Date(), // Initial value: now
  'MM/dd/yyyy hh:mm a' // Format: 12/31/2024 02:30 PM
).apply({
  icon: 'event',
  validator: Validators.required,
  minDate: new Date()
});

DateTime Picker with Clock Picker

const appointmentPicker = new DateTimePicker(
  'appointment',
  'Appointment Date & Time',
  null,
  'dd-MM-yyyy HH:mm' // Format: 31-12-2024 14:30
).apply({
  showClockPicker: true,
  orientation: 'portrait',
  icon: 'schedule',
  validator: Validators.required,
  hint: 'Select date and time for your appointment'
});

Business Hours Only

const businessMeetingPicker = new DateTimePicker(
  'businessMeeting',
  'Meeting',
  null,
  'EEEE, MMMM d, yyyy \u2018at\u2019 h:mm a' // Format: Monday, December 31, 2024 at 2:30 PM
).apply({
  minDate: new Date(),
  icon: 'business',
  validator: Validators.required,
  hint: 'Business hours: Mon-Fri, 9 AM - 5 PM'
});

Custom Labels

const customPicker = new DateTimePicker(
  'deadline',
  'Project Deadline',
  null,
  'yyyy-MM-dd HH:mm'
).apply({
  acceptLabel: 'Confirm',
  cancelLabel: 'Cancel',
  selectTimeLabel: 'Choose Time',
  enterTimeLabel: 'Type Time',
  minDate: new Date(),
  icon: 'alarm'
});

Landscape Orientation

const landscapePicker = new DateTimePicker(
  'event',
  'Event Date & Time',
  null,
  'MMM dd, yyyy - HH:mm'
).apply({
  orientation: 'landscape',
  showClockPicker: true,
  icon: 'event'
});

Properties

id
string
required
Unique identifier for the datetime picker.
placeholder
string
Label text for the datetime picker.
value
Date | string
Initial selected date and time.
dateFormat
string
default:"'dd-MM-yyyy hh:mm a'"
Display format for the selected date and time. Examples:
  • 'dd-MM-yyyy hh:mm a' → 31-12-2024 02:30 PM
  • 'MM/dd/yyyy HH:mm' → 12/31/2024 14:30
  • 'yyyy-MM-dd HH:mm:ss' → 2024-12-31 14:30:00
minDate
Date
Minimum selectable date. Dates before this are disabled.
maxDate
Date
Maximum selectable date. Dates after this are disabled.
acceptLabel
string
default:"'OK'"
Label for the confirm/accept button.
cancelLabel
string
default:"'Cancel'"
Label for the cancel button.
selectTimeLabel
string
default:"'Select Time'"
Label for the time selection header.
enterTimeLabel
string
default:"'Enter Time'"
Label for manual time entry mode.
showClockPicker
boolean
default:"false"
Whether to show the visual clock picker for time selection.
orientation
'portrait' | 'landscape'
default:"'portrait'"
Picker dialog orientation.
icon
string
Material icon name to display.
validator
ValidatorFn | ValidatorFn[]
Angular validators to apply.
errorMessage
string
Custom error message shown when validation fails.
hint
string
Helper text displayed below the picker.
disabled
boolean
default:"false"
Whether the picker is disabled.
singleLine
boolean
default:"false"
Whether the picker takes up a full row in the form grid.

Date Format Patterns

Use these patterns to customize the display format:
PatternExampleDescription
yyyy2024Full year
yy24Short year
MMMMDecemberFull month name
MMMDecShort month name
MM12Month number (01-12)
dd31Day of month (01-31)
EEEEMondayFull day name
EEEMonShort day name
HH14Hour (00-23)
hh02Hour (01-12)
mm30Minutes (00-59)
ss45Seconds (00-59)
aPMAM/PM marker

Common Format Examples

// US Format: 12/31/2024 2:30 PM
new DateTimePicker('dt', 'DateTime', null, 'MM/dd/yyyy h:mm a')

// European Format: 31-12-2024 14:30
new DateTimePicker('dt', 'DateTime', null, 'dd-MM-yyyy HH:mm')

// ISO Format: 2024-12-31 14:30:00
new DateTimePicker('dt', 'DateTime', null, 'yyyy-MM-dd HH:mm:ss')

// Readable Format: Monday, December 31, 2024 at 2:30 PM
new DateTimePicker('dt', 'DateTime', null, 'EEEE, MMMM d, yyyy \u2018at\u2019 h:mm a')

// Short Format: Dec 31, 2024 - 14:30
new DateTimePicker('dt', 'DateTime', null, 'MMM dd, yyyy - HH:mm')

Validation Examples

Required DateTime

import { Validators } from '@angular/forms';

const picker = new DateTimePicker('datetime', 'Date & Time', null, 'MM/dd/yyyy hh:mm a').apply({
  validator: Validators.required,
  errorMessage: 'Date and time are required'
});

Future DateTime Only

import { AbstractControl, ValidationErrors } from '@angular/forms';

function futureDateTimeValidator(control: AbstractControl): ValidationErrors | null {
  if (!control.value) return null;
  
  const selectedDateTime = new Date(control.value);
  const now = new Date();
  
  if (selectedDateTime <= now) {
    return { pastDateTime: true };
  }
  
  return null;
}

const picker = new DateTimePicker('appointment', 'Appointment', null, 'MM/dd/yyyy hh:mm a').apply({
  validator: [Validators.required, futureDateTimeValidator],
  errorMessage: 'Please select a future date and time',
  minDate: new Date()
});

Business Hours Validator

function businessHoursValidator(control: AbstractControl): ValidationErrors | null {
  if (!control.value) return null;
  
  const dateTime = new Date(control.value);
  const day = dateTime.getDay(); // 0 = Sunday, 6 = Saturday
  const hour = dateTime.getHours();
  
  // Check if weekend
  if (day === 0 || day === 6) {
    return { weekend: true };
  }
  
  // Check if outside business hours (9 AM - 5 PM)
  if (hour < 9 || hour >= 17) {
    return { outsideBusinessHours: true };
  }
  
  return null;
}

const picker = new DateTimePicker('meeting', 'Meeting Time', null, 'MM/dd/yyyy hh:mm a').apply({
  validator: [Validators.required, businessHoursValidator],
  errorMessage: 'Meetings must be scheduled Mon-Fri, 9 AM - 5 PM',
  hint: 'Business hours only'
});

Complete Example

import { Component } from '@angular/core';
import { Validators } from '@angular/forms';
import { FormStructure, Input, DateTimePicker, TextArea, Button } from 'mat-dynamic-form';

@Component({
  selector: 'app-appointment-form',
  template: '<mat-dynamic-form [structure]="formStructure"></mat-dynamic-form>'
})
export class AppointmentFormComponent {
  formStructure: FormStructure;
  
  constructor() {
    this.formStructure = new FormStructure('Schedule Appointment');
    this.formStructure.appearance = 'outline';
    this.formStructure.nodeGrid = 2;
    
    // Set date constraints
    const now = new Date();
    const threeMonthsFromNow = new Date();
    threeMonthsFromNow.setMonth(threeMonthsFromNow.getMonth() + 3);
    
    this.formStructure.nodes = [
      new Input('name', 'Full Name').apply({
        icon: 'person',
        validator: Validators.required,
        singleLine: true
      }),
      
      new Input('email', 'Email').apply({
        icon: 'email',
        validator: [Validators.required, Validators.email],
        singleLine: true
      }),
      
      new Input('phone', 'Phone Number').apply({
        icon: 'phone',
        validator: Validators.required
      }),
      
      new DateTimePicker(
        'appointmentDateTime',
        'Appointment Date & Time',
        null,
        'EEEE, MMMM d, yyyy \u2018at\u2019 h:mm a'
      ).apply({
        minDate: now,
        maxDate: threeMonthsFromNow,
        showClockPicker: true,
        orientation: 'portrait',
        acceptLabel: 'Confirm',
        cancelLabel: 'Cancel',
        icon: 'event',
        validator: Validators.required,
        hint: 'Available Mon-Fri, 9 AM - 5 PM',
        singleLine: false
      }),
      
      new TextArea(
        'notes',
        'Additional Notes',
        '',
        500
      ).apply({
        icon: 'notes',
        hint: 'Any special requirements or questions',
        singleLine: true
      })
    ];
    
    this.formStructure.validateActions = [
      new Button('reset', 'Clear', {
        style: 'warn',
        onEvent: (param) => {
          param.structure.reset();
          param.structure.remapValues();
        }
      }).apply({
        icon: 'clear'
      }),
      
      new Button('submit', 'Schedule Appointment', {
        style: 'primary',
        onEvent: (param) => this.onSubmit(param.structure)
      }).apply({
        validateForm: true,
        icon: 'check'
      })
    ];
  }
  
  onSubmit(structure: FormStructure) {
    const data = structure.getValue();
    console.log('Appointment data:', data);
    
    // Format datetime for display
    const appointmentDate = new Date(data.appointmentDateTime);
    console.log('Scheduled for:', appointmentDate.toLocaleString());
    
    // Send to API
    // this.appointmentService.schedule(data).subscribe(...);
  }
}

Best Practices

Choose appropriate date formats - Use formats familiar to your users:
  • US: MM/dd/yyyy hh:mm a
  • Europe: dd-MM-yyyy HH:mm
  • ISO: yyyy-MM-dd HH:mm
Enable clock picker for better UX - The visual clock picker (showClockPicker: true) is more intuitive than typing time:
showClockPicker: true
Handle timezone carefully - DateTime values are in the user’s local timezone. For server communication, convert to UTC:
const utcDate = new Date(localDate).toISOString();
Set reasonable date constraints - Prevent invalid selections:
minDate: new Date(), // No past dates
maxDate: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000) // 90 days ahead
Provide clear hints - Tell users about scheduling constraints:
hint: 'Business hours: Mon-Fri, 9 AM - 5 PM'
hint: 'Appointments available up to 3 months in advance'
Use portrait orientation for mobile - Portrait orientation works better on smaller screens:
orientation: 'portrait'

Working with DateTime Values

Getting DateTime Value

const formData = formStructure.getValue();
const appointmentDateTime = formData.appointment;

// Convert to Date object
const date = new Date(appointmentDateTime);

console.log('Date:', date.toLocaleDateString());
console.log('Time:', date.toLocaleTimeString());
console.log('ISO:', date.toISOString());

Setting DateTime Programmatically

// Set to now
formStructure.patchValue({
  appointment: new Date()
});

// Set specific datetime
const specificDateTime = new Date(2024, 11, 31, 14, 30); // Dec 31, 2024 2:30 PM
formStructure.patchValue({
  appointment: specificDateTime
});

// Set to tomorrow at 10 AM
const tomorrow10AM = new Date();
tomorrow10AM.setDate(tomorrow10AM.getDate() + 1);
tomorrow10AM.setHours(10, 0, 0, 0);
formStructure.patchValue({
  appointment: tomorrow10AM
});

Date Picker

Select date only (no time)

Time Picker

Select time only (no date)

Date Range Picker

Select start and end dates

See Also

Build docs developers (and LLMs) love