The problem is as follows: current time changes constantly, each mome
CurrentTime: any;
constructor() {
setInterval(() => {
this.CurrentTime = new Date().getHours() + ':' + new Date().getMinutes() + ':'+ new Date().getSeconds()}, 1);
}
First of all you don't need to call ChangeDetectorRef.detectChanges()
inside your interval, because angular is using Zone.js
which monkey patches the browsers setInteral
method with its own. Therefore angular is well aware of the changes happening during an interval.
You should set the time inside your interval like this:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `{{ now }}`
})
export class AppComponent {
public now: Date = new Date();
constructor() {
setInterval(() => {
this.now = new Date();
}, 1);
}
}
But you shouldn't update the time on such a high rate, because it would lead to poor perfomance, because everytime the date updates angular performs a changedetection on the component tree.
If you want to update the DOM at a very high rate, you should use runOutsideAngular
from NgZone
and update the DOM manually using the Renderer2
.
For example:
@Component({
selector: 'my-counter',
template: '<span #counter></span>'
})
class CounterComponent implements OnChange {
public count: number = 0;
@ViewChild('counter')
public myCounter: ElementRef;
constructor(private zone: NgZone, private renderer: Renderer2) {
this.zone.runOutsideAngular(() => {
setInterval(() => {
this.renderer.setProperty(this.myCounter.nativeElement, 'textContent', ++this.count);
}, 1);
});
}
}
As per Angular documentation on the DatePipe
Link, Date.now()
can be used.
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `{{ now | date:'HH:mm:ss'}}`
})
export class AppComponent {
now:number;
constructor() {
setInterval(() => {
this.now = Date.now();
}, 1);
}
}
today: number = Date.now();
constructor() {
setInterval(() => {this.today = Date.now()}, 1);
}
If you want to format this on html page, use it like this:
<p>{{today | date:'fullDate'}} {{today | date:'h:mm:ss a'}}</p>
I'm adding one more point, which I was finding and could come closer to my solution because of this answer, so for another one who's seeking a similar thing, I'm adding this too :)
If you want to get [Year: Month :date :hours: minutes with am/pm ] format with all numbers (ex : 12 instead of the string "December"), simply use the following
<p>{{today | date:'y:M:d:h:mm a'}}</p>
Actually, you don't need any library for this simple task. If you are doing in your angular project with angular 6+ then import formatDate from the common package and pass other data. Here is a sample:
import { Component } from '@angular/core';
import {formatDate } from '@angular/common';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
today= new Date();
todaysDataTime = '';
constructor() {
this.todaysDataTime = formatDate(this.today, 'dd-MM-yyyy hh:mm:ss a', 'en-US', '+0530');
}
}
Here is a stackblitz link, you can edit here: https://stackblitz.com/edit/angular-h63y8e
Use arrow function.
constructor(cd: ChangeDetectorRef){
setInterval(() => { cd.detectChanges(); }, 1);
}