简体   繁体   中英

Use filters to format date in a custom format

I am trying to display some dates with a custom format on my angular app: I'd like to see "1 hour ago", "2 days ago"... rather than the actual time so I was thinking of using filters to do this.

My dates are stored with MongoDb so I receive them as ISODate:

ISODate("2014-03-13T10:48:02.991Z")

Basically I would like to apply this function to my dates:

function timeSince(ts){
    now = new Date();
    ts = new Date(ts*1000);
    var delta = now.getTime() - ts.toString().getTime();

    delta = delta/1000; //us to s

    var ps, pm, ph, pd, min, hou, sec, days;

    if(delta<=59){
        ps = (delta>1) ? "s": "";
        return delta+" second"+ps
    }

    if(delta>=60 && delta<=3599){
        min = Math.floor(delta/60);
        sec = delta-(min*60);
        pm = (min>1) ? "s": "";
        ps = (sec>1) ? "s": "";
        return min+" minute"+pm+" "+sec+" second"+ps;
    }

    if(delta>=3600 && delta<=86399){
        hou = Math.floor(delta/3600);
        min = Math.floor((delta-(hou*3600))/60);
        ph = (hou>1) ? "s": "";
        pm = (min>1) ? "s": "";
        return hou+" hour"+ph+" "+min+" minute"+pm;
    } 

    if(delta>=86400){
        days = Math.floor(delta/86400);
        hou =  Math.floor((delta-(days*86400))/60/60);
        pd = (days>1) ? "s": "";
        ph = (hou>1) ? "s": "";
        return days+" day"+pd+" "+hou+" hour"+ph;
    }

}

How can I do this simply using filters?

Thanks

are you looking for a basic angular filter template? this is how you should wrap your code with an angular filter.

angular.module('MyModule', []).
  filter('timeSince', function() {
    return function(input) {

    var now = new Date();
    var ts = new Date(input);
    var delta = now.getTime() - ts.toString().getTime();

    delta = delta/1000; //us to s

    var ps, pm, ph, pd, min, hou, sec, days;

    if(delta<=59){
        ps = (delta>1) ? "s": "";
        return delta+" second"+ps
    }

    if(delta>=60 && delta<=3599){
        min = Math.floor(delta/60);
        sec = delta-(min*60);
        pm = (min>1) ? "s": "";
        ps = (sec>1) ? "s": "";
        return min+" minute"+pm+" "+sec+" second"+ps;
    }

    if(delta>=3600 && delta<=86399){
        hou = Math.floor(delta/3600);
        min = Math.floor((delta-(hou*3600))/60);
        ph = (hou>1) ? "s": "";
        pm = (min>1) ? "s": "";
        return hou+" hour"+ph+" "+min+" minute"+pm;
    } 

    if(delta>=86400){
        days = Math.floor(delta/86400);
        hou =  Math.floor((delta-(days*86400))/60/60);
        pd = (days>1) ? "s": "";
        ph = (hou>1) ? "s": "";
        return days+" day"+pd+" "+hou+" hour"+ph;
    }

    return "-";
    };
  });

use in markup : Time since: {{this_should_be_the_ISODate_from_model | timeSince}}

You just need to create a filter that returns that function.

myModule.filter('prettyTime', function(){

   return function(ts){
      //Your code here
   };

});

And assuming you have some Date object on your $scope somewhere:

<span>{{time | prettyTime}}</span>

Here is a working demo: http://jsfiddle.net/jwcarroll/ARc65/

With Moment.js , this is as simple as:

App.filter('ago', function(){
  return function(epoch){
    var diff = Date.now() - parseInt(epoch,10);
    return moment.duration(diff).humanize() + ' ago';
  };
});

Moment.js on CDNJS

Edit: Moment will also parse various ISO types, see docs

Usage is as @Josh mentions:

<span>{{ time | ago }}</span>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM