13

I'm trying to create post sharing web site. I want to create date ago pipe in angular.

    import {Pipe, PipeTransform} from 'angular2/core';

@Pipe({
  name: 'messageTime',
  pure: false
})
export class MessageTimePipe implements PipeTransform {
  transform(value: Date, []): string {
    var result: string;

    // current time
    let now = new Date().getTime();

    // time since message was sent in seconds
    let delta = (now - value.getTime()) / 1000;

    // format string
    if (delta < 10) {
      result = 'jetzt';
    } else if (delta < 60) { // sent in last minute
      result = 'vor ' + Math.floor(delta) + ' Sekunden';
    } else if (delta < 3600) { // sent in last hour
      result = 'vor ' + Math.floor(delta / 60) + ' Minuten';
    } else if (delta < 86400) { // sent on last day
      result = 'vor ' + Math.floor(delta / 3600) + ' Stunden';
    } else { // sent more than one day ago
      result = 'vor ' + Math.floor(delta / 86400) + ' Tagen';
    }

    return result;
  }enter code here
}

I trying like above code in my project. But it doesn't work corectly.

abhay tripathi
  • 3,547
  • 4
  • 20
  • 25
Jihar Steew
  • 141
  • 1
  • 1
  • 6
  • It would be helpful if you could describe how it does'nt work correctly. E.g. give sample output or explain why you think it might be faulty. Just pasting the whole pipe code shows lack of effort and is unlikely to get you a lot of good responses. – kacase Apr 21 '20 at 12:11

4 Answers4

26

first create pipe class

ng g p pipes/DateAgo

Let's add these code,

  import {Pipe, PipeTransform} from '@angular/core';

@Pipe({
    name: 'dateAgo',
    pure: true
})
export class DateAgoPipe implements PipeTransform {

    transform(value: any, args?: any): any {
        if (value) {
            const seconds = Math.floor((+new Date() - +new Date(value)) / 1000);
            if (seconds < 29) // less than 30 seconds ago will show as 'Just now'
                return 'Just now';
            const intervals: { [key: string]: number } = {
                'year': 31536000,
                'month': 2592000,
                'week': 604800,
                'day': 86400,
                'hour': 3600,
                'minute': 60,
                'second': 1
            };
            let counter;
            for (const i in intervals) {
                counter = Math.floor(seconds / intervals[i]);
                if (counter > 0)
                    if (counter === 1) {
                        return counter + ' ' + i + ' ago'; // singular (1 day ago)
                    } else {
                        return counter + ' ' + i + 's ago'; // plural (2 days ago)
                    }
            }
        }
        return value;
    }

}
Seanvm
  • 394
  • 1
  • 9
12

I think it's better to use one of the following packages to get a time ago functionality rather than creating your own, for few reasons like quick implementation / maintenance / new features and fixes / etc

  • ngx-timeago (would be my choice)

    This one is having features that the other don't have e.g. i18n, live changes to the time ago text, etc.

  • time-ago-pipe

    This is a simple 'pipe only' package, therefore it's light weight and simple to use.

  • ngx-moment

    Suggestion: use this one only if you're already using moment.js in your app as this is about to become a legacy project and it will add a lot of weight to your bundle size (see comments below, thanks @ymerej and @Alexandre Germain).

  • Angular Intl

    Here is a new one that looks quite good as well, it got i18n support and an option to change the time ago description as well.

benshabatnoam
  • 7,161
  • 1
  • 31
  • 52
  • 1
    Much much better than implementing yourself. Make sure to load the correct locale in your initialization code with `moment.locale('fr-FR')`. – John White Jan 15 '21 at 08:18
  • 3
    Just an FYI, if you're not using momentjs, you'll bloat your bundle by ~500kb. Not worth it for something like this. – ymerej Mar 06 '21 at 20:24
  • 1
    As mentioned in [their own documentation](https://momentjs.com/docs/), momentjs doesn't recommend new projects to use it. > We now generally consider Moment to be a legacy project in maintenance mode. It is not dead, but it is indeed done. – Alexandre Germain Mar 08 '21 at 22:50
  • Thanks @ymerej you are absolutely right, I'll update my answer for more packages options. – benshabatnoam Mar 16 '21 at 08:19
  • I created a package which contains a `relativeTime` pipe, and it supports i18n out of the box. You can [view the demo here](https://json-derulo.github.io/angular-ecmascript-intl/#/pipes/relative-time). Would you mind adding it to the list? – JSON Derulo Mar 03 '23 at 21:24
  • Nice, I'll add it, NP – benshabatnoam Mar 04 '23 at 19:03
1

Better use moment to create pipe. After lots of findings and research, I got this.

Create a pipe

ng g pipe pipes/timeAgo

Write this code. Actually one line you have to change, others will generate automatically

import { Pipe, PipeTransform } from '@angular/core';
import moment from 'moment';

@Pipe({
  name: 'timeAgo'
})
export class TimeAgoPipe implements PipeTransform {

  transform(value: Date, ...args: unknown[]): unknown {
    return moment(value).fromNow(); // this line you have to edit
  }

}
<span class="timeago-label">{{'2023-07-10T06:00:00Z' | timeAgo}}</span>

You need to install moment for that

npm i moment --save
BikyMandal
  • 41
  • 4
  • You can also use observables to make the pipe update automatically! https://stackoverflow.com/questions/69274146/ – AvahW Jul 23 '23 at 20:36
0

Create a pipe using this command : "ng g p customePipe/timeAgo"

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'timeAgo'
})
export class TimeAgoPipe implements PipeTransform {
  transform(value: string): string {
    const time = new Date(value);
    const now = new Date();
    const seconds = Math.floor((now.getTime() - time.getTime()) / 1000);

    if (seconds < 60) {
      return 'just now';
    } else if (seconds < 120) {
      return 'a minute ago';
    } else if (seconds < 3600) {
      return Math.floor(seconds / 60) + ' minutes ago';
    } else if (seconds < 7200) {
      return 'an hour ago';
    } else if (seconds < 86400) {
      return Math.floor(seconds / 3600) + ' hours ago';
    } else {
      return time.toLocaleString();
    }
  }
}
Rohit Soni
  • 47
  • 1
  • 1
  • 6