import { Pipe , PipeTransform , NgZone , ChangeDetectorRef , OnDestroy } from '@angular/core' ; @ Pipe ( { name : 'timeDiff' , pure : false } ) export class TimeDiffPipe implements PipeTransform , OnDestroy { private timer : number ; constructor ( private changeDetectorRef , private ngZone ) { } transform ( value ) { this . removeTimer ( ) ; const d = new Date ( value ) ; const now = new Date ( ) ; let seconds = Math . round ( ( now . getTime ( ) - d . getTime ( ) ) / 1000 ) ; const isFuture = seconds < 0 ; seconds = Math . abs ( seconds ) ; const timeToUpdate = this . getSecondsUntilUpdate ( seconds ) * 1000 ; this . timer = this . ngZone . runOutsideAngular ( ( ) => { if ( typeof window !== 'undefined' ) { return window . setTimeout ( ( ) => { this . ngZone . run ( ( ) => this . changeDetectorRef . markForCheck ( ) ) ; } , timeToUpdate ) ; } return null ; } ) ; const minutes = Math . round ( Math . abs ( seconds / 60 ) ) ; const hours = Math . round ( Math . abs ( minutes / 60 ) ) ; const days = Math . round ( Math . abs ( hours / 24 ) ) ; const months = Math . round ( Math . abs ( days / 30.44 ) ) ; const years = Math . round ( Math . abs ( days / 365 ) ) ; return this . calculateString ( isFuture , seconds , minutes , hours , days , months , years ) ; } ngOnDestroy ( ) { this . removeTimer ( ) ; } private removeTimer ( ) { if ( this . timer ) { window . clearTimeout ( this . timer ) ; this . timer = null ; } } private getSecondsUntilUpdate ( seconds ) { const min = 60 ; const hr = min * 60 ; const day = hr * 24 ; if ( seconds < min ) { return 2 ; } else if ( seconds < hr ) { return 30 ; } else if ( seconds < day ) { return 300 ; } else { return 3600 ; } } private calculateString ( isFuture , seconds , minutes , hours , days , months , years ) { if ( seconds <= 5 && ! isFuture ) { return 'just now' ; } let statement ; if ( seconds <= 45 ) { statement = 'a few seconds' ; } else if ( seconds <= 90 ) { statement = '1 minute' ; } else if ( minutes <= 45 ) { statement = minutes + ' minutes' ; } else if ( minutes <= 90 ) { statement = 'an hour' ; } else if ( hours <= 22 ) { statement = hours + ' hours' ; } else if ( hours <= 36 ) { statement = 'a day' ; } else if ( days <= 25 ) { statement = days + ' days' ; } else if ( days <= 45 ) { statement = 'a month' ; } else if ( days <= 345 ) { statement = months + ' months' ; } else if ( days <= 545 ) { statement = 'a year' ; } else { statement = years + ' years' ; } return isFuture ? `in ${ statement }` : `${ statement } ago` ; } }