diff --git a/src/ng-pipes/pipes/date/index.ts b/src/ng-pipes/pipes/date/index.ts index e2ad0b8f..bf2dce97 100644 --- a/src/ng-pipes/pipes/date/index.ts +++ b/src/ng-pipes/pipes/date/index.ts @@ -1,7 +1,8 @@ import { NgModule } from '@angular/core'; import { TimeAgoPipe } from './time-ago'; +import { TimeToPipe } from './time-to.pipe'; -export const DATE_PIPES = [TimeAgoPipe]; +export const DATE_PIPES = [TimeAgoPipe, TimeToPipe]; @NgModule({ declarations: DATE_PIPES, @@ -11,3 +12,4 @@ export const DATE_PIPES = [TimeAgoPipe]; export class NgDatePipesModule {} export { TimeAgoPipe } from './time-ago'; +export {TimeToPipe} from './time-to.pipe'; diff --git a/src/ng-pipes/pipes/date/time-to.pipe.spec.ts b/src/ng-pipes/pipes/date/time-to.pipe.spec.ts new file mode 100644 index 00000000..94805950 --- /dev/null +++ b/src/ng-pipes/pipes/date/time-to.pipe.spec.ts @@ -0,0 +1,116 @@ +import { TimeToPipe } from './time-to.pipe'; + + +describe('TimeToPipe', () => { + let pipe: TimeToPipe; + const today = new Date(); + const past = new Date(today.getTime() - 1000 * 20); + + const recentlyString = 'just now'; + const pastString = 'in the past'; + + const fewSecondsAgoDate = new Date(today.getTime() + 5 * 1000); + const aMinuteAgoDate = new Date(today.getTime() + 60 * 1000); + + const fewMinutesToString = 5 + ' minutes to'; + const fewMinutesToDate = new Date(new Date().getTime() + 5 * 60 * 1000); + + const anHourToString = 'in an hour'; + const anHourToDate = new Date(new Date().getTime() + 60 * 60 * 1000); + + const fewHoursToString = 5 + ' hours to'; + const fewHoursToDate = new Date(new Date().getTime() + 5 * 60 * 60 * 1000); + + const tomorrowString = 'tomorrow'; + const tomorrowDate = new Date(new Date().setDate(new Date().getDate() + 1)); + + const fewDaysToString = 3 + ' days to'; + const fewDaysToDate = new Date(new Date().setDate(new Date().getDate() + 3)); + + const nextWeekString = 'next week'; + const nextWeekDate = new Date(new Date().setDate(new Date().getDate() + 7)); + + const fewWeeksToString = 2 + ' weeks to'; + const fewWeeksToDate = new Date(new Date().setDate(new Date().getDate() + 14)); + + const nextMonthString = 'next month'; + const nextMonthDate = new Date(new Date().setDate(new Date().getDate() + 30)); + + const fewMonthsToString = 5 + ' months to'; + const fewMonthsToDate = new Date(new Date().setDate(new Date().getDate() + 30 * 5)); + + const nextYearString = 'next year'; + const nextYearDate = new Date(new Date().setDate(new Date().getDate() + 366)); + + const fewYearsToString = 5 + ' years to'; + const fewYearsToDate = new Date(new Date().setDate(new Date().getDate() + 366 * 5)); + + + beforeAll(() => { + pipe = new TimeToPipe(); + }); + + it('should return just now', () => { + expect(pipe.transform(new Date())).toEqual(recentlyString); + }); + + it('should return just now', () => { + expect(pipe.transform(fewSecondsAgoDate)).toEqual(recentlyString); + }); + + it('should return just now', () => { + expect(pipe.transform(aMinuteAgoDate)).toEqual(recentlyString); + }); + + it('should return in the past', () => { + expect(pipe.transform(past)).toEqual(pastString); + }); + + it('should return 5 minutes ago', () => { + expect(pipe.transform(fewMinutesToDate)).toEqual(fewMinutesToString); + }); + + it('should return an hour to', () => { + expect(pipe.transform(anHourToDate)).toEqual(anHourToString); + }); + + it('should return 5 hours to', () => { + expect(pipe.transform(fewHoursToDate)).toEqual(fewHoursToString); + }); + + it('should return tomorrow', () => { + expect(pipe.transform(tomorrowDate)).toEqual(tomorrowString); + }); + + it('should return 5 days to', () => { + expect(pipe.transform(fewDaysToDate)).toEqual(fewDaysToString); + }); + + it('should return next week', () => { + expect(pipe.transform(nextWeekDate)).toEqual(nextWeekString); + }); + + it('should return 2 weeks to', () => { + expect(pipe.transform(fewWeeksToDate)).toEqual(fewWeeksToString); + }); + + it('should return next month', () => { + expect(pipe.transform(nextMonthDate)).toEqual(nextMonthString); + }); + + it('should return 5 months to', () => { + expect(pipe.transform(fewMonthsToDate)).toEqual(fewMonthsToString); + }); + + it('should return next year', () => { + expect(pipe.transform(nextYearDate)).toEqual(nextYearString); + }); + + it('should return 5 years to', () => { + expect(pipe.transform(fewYearsToDate)).toEqual(fewYearsToString); + }); + + + +}); + diff --git a/src/ng-pipes/pipes/date/time-to.pipe.ts b/src/ng-pipes/pipes/date/time-to.pipe.ts new file mode 100644 index 00000000..605433ff --- /dev/null +++ b/src/ng-pipes/pipes/date/time-to.pipe.ts @@ -0,0 +1,47 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'timeTo', +}) +export class TimeToPipe implements PipeTransform { + + private static YEAR_MS: number = 1000 * 60 * 60 * 24 * 7 * 4 * 12; + private static MAPPER: any = [ + { single: 'next year', many: 'years', div: 1 }, + { single: 'next month', many: 'months', div: 12 }, + { single: 'next week', many: 'weeks', div: 4 }, + { single: 'tomorrow', many: 'days', div: 7 }, + { single: 'in an hour', many: 'hours', div: 24 }, + { single: 'just now', many: 'minutes', div: 60 }, + ]; + + transform(inputDate: any): string { + if (!inputDate || (!inputDate.getTime && !inputDate.toDate)) { + return 'Invalid date'; + } + + + + const future = inputDate.toDate ? inputDate.toDate() : inputDate.getTime(); + const now = +new Date(); + console.log(new Date(future)); + console.log(new Date(now)); + + if (future < now) { + return 'in the past'; + } + + + for (let i = 0, l = TimeToPipe.MAPPER.length, ms = future - now, div = TimeToPipe.YEAR_MS; i < l; i++) { + const elm = TimeToPipe.MAPPER[i]; + + const unit = Math.round(ms / (div /= elm.div)); + if (unit >= 1) { + return unit === 1 ? elm.single : `${unit} ${elm.many} to`; + } + } + + return 'just now'; + } + +}