Getting Moment JS to display time ago up to yesterday then start displaying a formatted date

0 votes
asked Sep 13, 2017 by camitose

Disclaimer: I'm very new to javascript (and angular).

I'm trying to get momentjs to display the time from now up till yesterday. Once it's been 3 days it would display the actual date.

Example using random date (date diff will always be "today"):

  • 10/10/17 at 6:41 pm (future)
  • Tomorrow at 6:41 pm
  • Today at 6:41 pm
  • Yesterday at 6:41 pm
  • 10/10/17 at 6:41 pm

Not sure what other information I should provide but please ask if anything helps.

3 Answers

0 votes
answered Sep 13, 2017 by apoorv-joshi

There are a couple of functions that can be helpful in getting the expected output.

  1. moment.format(): You can use it to format the string like you want it. For example: moment.format("dd/MM/YY at hh:mm:ss")
  2. moment.isSame(): To determine if the date is same as today.
  3. moment.diff(): To determine the differece between dates.

Here's a solution based on what you expect the output to be:

0 votes
answered Sep 13, 2017 by sheminusminus

I'm not sure how much you've familiarized with moment so far, so here's one way to do it, from the beginning:

// get today's date and time
var now = moment();

// will hold our display string (we'll set this in a minute)
var displayValue = '';

// target date & time in string format (YYYY-MM-DD hh:mm)
// you can also use a JavaScript date object instead of a string
var dateString = '2017-10-10 06:41';

// create a moment wrapper for the past/future date
var targetDate = moment(dateString);

// how many total days difference between then and now?
// calling moment() with no args defaults to current date and time
// first argument to `diff` is the date to subtract
// second argument is the unit of time to measure in
var difference = now.diff(targetDate, 'days');

if (difference > 3 || difference < -3) {
    // if the date is more than three days in the past or more than three days into the future...
    displayValue = targetDate.format('MM-DD-YYYY') + ' at ' + targetDate.format('hh:mm');
} else {
    // otherwise...
    displayValue = targetDate.fromNow();

console.log(displayValue); // > "10-10-2017 at 06:41"

Edit: If the target date happens to be today, and you want to display 'Today' instead of moment's default '15 hours ago', just check for a difference of 0.

if (difference === 0) displayValue = 'Today at ' + targetDate.format('hh:mm');

Edit: Created a variable for 'now', for clarity.

0 votes
answered Sep 14, 2017 by camitose

Thanks everyone for input. Using your examples I was able to solve the problem. Shortly after I found a much better way to do what I wanted which I will share here.

Using momentJS calendar feature makes doing this very simple. Here is my filter which does precisely what I wanted plus a some extra features.

//This filter will display today, tomorrow, yesterday then display the actual date as 'M/D/Y at h:mm a'.
//Default preposition is 'at', but any other can be passed in as the second parameter.
.filter('formatForTimeAgo', function () {
  return function timeTodayDateElse(date, preposition){
    preposition=preposition|| 'at'
    moment.lang('en', {
      'calendar' : {
        'lastDay'  : '[Yesterday] [\n][ '+preposition+' ] h:mm a',
        'sameDay'  : '[Today] [\n][ '+preposition+' ] h:mm a',
        'nextDay'  : '[Tomorrow] [\n][ '+preposition+' ] h:mm a',
        'lastWeek' : 'M/D/YY [\n]['+preposition+'] h:mm a',
        'nextWeek' : 'M/D/YY [\n]['+preposition+'] h:mm a',
        'sameElse' : 'M/D/YY [\n]['+preposition+'] h:mm a'
    return moment(date).calendar();
Welcome to Q&A, where you can ask questions and receive answers from other members of the community.