Last active
March 7, 2023 15:10
-
-
Save SnisarOnline/d0b3e4d417ec7b73cf3f559e96b11fc0 to your computer and use it in GitHub Desktop.
An Angular pipe for converting a date string into a time ago
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Angular | |
import { Pipe, PipeTransform, OnDestroy, ChangeDetectorRef, NgZone } from '@angular/core'; | |
/** | |
* https://github.com/AndrewPoyntz/time-ago-pipe | |
* An Angular pipe for converting a date string into a time ago | |
* | |
* Example : | |
* <span>Last {{ date | kTimeElapsed}} ago</span> | |
*/ | |
@Pipe({ | |
name: 'kTimeElapsed' | |
}) | |
export class TimeElapsedPipe implements PipeTransform, OnDestroy { | |
private _timer: number; | |
/** | |
* Pipe Constructor | |
* | |
* @param changeDetectorRef: ChangeDetectorRef | |
* @param ngZone: NgZone | |
*/ | |
constructor( | |
private changeDetectorRef: ChangeDetectorRef, | |
private ngZone: NgZone | |
) {} | |
/** | |
* @ Lifecycle sequences => https://angular.io/guide/lifecycle-hooks | |
*/ | |
ngOnDestroy(): void { | |
this.removeTimer(); | |
} | |
/** | |
* Transform | |
* | |
* @param value: string time | |
* @param textBefore: string - text Before calculated time | |
* @param textAfter: string - text after calculated time | |
*/ | |
transform(value: string, textBefore?: string, textAfter?: string): string { | |
this.removeTimer(); | |
let timeElapsed: string = ''; | |
if (!value) { | |
return timeElapsed; | |
} | |
const d = new Date(value); | |
const now = new Date(); | |
const seconds = Math.round(Math.abs((now.getTime() - d.getTime()) / 1000)); | |
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.416)); | |
const years = Math.round(Math.abs(days / 365)); | |
if (seconds <= 45) { | |
timeElapsed = 'just now'; | |
} else if (seconds <= 90) { | |
timeElapsed = `${textBefore} 1 min ${textAfter}`; | |
} else if (minutes <= 45) { | |
timeElapsed = `${textBefore} ${minutes} mins ${textAfter}`; | |
} else if (minutes <= 90) { | |
timeElapsed = `${textBefore} 1 hr ${textAfter}`; | |
} else if (hours <= 22) { | |
timeElapsed = `${textBefore} ${hours} hrs ${textAfter}`; | |
} else if (hours <= 36) { | |
timeElapsed = `${textBefore} 1 day ${textAfter}`; | |
} else if (days <= 25) { | |
timeElapsed = `${textBefore} ${days} days ${textAfter}`; | |
} else if (days <= 45) { | |
timeElapsed = `${textBefore} 1 month ${textAfter}`; | |
} else if (days <= 345) { | |
timeElapsed = `${textBefore} ${months} months ${textAfter}`; | |
} else if (days <= 545) { | |
timeElapsed = `${textBefore} 1 year ${textAfter}`; | |
} else { | |
// (days > 545) | |
timeElapsed = `${textBefore} ${years} years ${textAfter}`; | |
} | |
return this.capitalizeFirstLetter(timeElapsed); | |
} | |
/** | |
* Remove _timer | |
*/ | |
private removeTimer(): void { | |
if (this._timer) { | |
window.clearTimeout(this._timer); | |
this._timer = null; | |
} | |
} | |
/** | |
* Returns Seconds Until Update | |
* @param seconds: number | |
*/ | |
private getSecondsUntilUpdate(seconds: number): number { | |
const min = 60; | |
const hr = min * 60; | |
const day = hr * 24; | |
if (seconds < min) { | |
// less than 1 min, update ever 2 secs | |
return 2; | |
} else if (seconds < hr) { | |
// less than an hour, update every 30 secs | |
return 30; | |
} else if (seconds < day) { | |
// less then a day, update every 5 mins | |
return 300; | |
} else { | |
// update every hour | |
return 3600; | |
} | |
} | |
private capitalizeFirstLetter(str: string): string { | |
return str.charAt(0).toUpperCase() + str.slice(1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment