Bind datetime-local to a Date object in Angular

 For some reason, angular does not bind correctly an input with datetime-local type to a date object.

We have to create a component for this.

I found this post:

https://stackoverflow.com/a/34551704

Very useful.

Made some minor adaptations (to make it work with the new TypeScript restrictions)

import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-date-time',
  template: `<input type="datetime-local" [value] = "_date" 
           (change) = "onDateChange($event)" />`,
  styleUrls: ['./date-time.component.css']
})
export class DateTimeComponent{
  _date: string | null | undefined;

  @Input() set date(d: Date | null) {
      this._date = this.toDateString(d!);
  }
  @Output() dateChange: EventEmitter<Date>;
  constructor() {
      this.date = new Date();
      this.dateChange = new EventEmitter();       
  }

  private toDateString(date: Date): string {
      return (date.getFullYear().toString() + '-' 
         + ("0" + (date.getMonth() + 1)).slice(-2) + '-' 
         + ("0" + (date.getDate())).slice(-2))
         + 'T' + date.toTimeString().slice(0,5);
  }

  private parseDateString(date:string): Date {
     date = date.replace('T','-');
     var parts = date.split('-');
     var timeParts = parts[3].split(':');

    // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
    return new Date(+parts[0], +parts[1]-1, +parts[2], +timeParts[0], +timeParts[1]);     // Note: months are 0-based

  }

  onDateChange(event: any): void {
      let value = event.target.value

      if (value != this._date) {
          var parsedDate = this.parseDateString(value);

          // check if date is valid first

          if (parsedDate.getTime() != NaN) {
             this._date = value;
             this.dateChange.emit(parsedDate);
          }
      }
  }
}

Use it like this:

<app-date-time [(date)]="myDate"></app-date-time>

where myDate: Date = new Date();


Post a Comment

Previous Post Next Post