简体   繁体   中英

moment.js change format based on difference

I want to follow the same structure as content posting websites where new posts follow something like:

(seconds/minutes/hours ago), (yesterday), (days ago), (MMM Do YY) .

How would I rearrange the JS to follow this format and go to (MMM Do YY) after say, 3 days ?

 // iterates over every element with the .js-time-ago css class $('.date').each(function() { var $this = $(this), textDate = $this.data('date'), // gets the date from the date attribute postedDate = moment(textDate, ['DDMMMMY', 'MMMMDDY']).format(), // formats the date in a formate that will continue to be supported by Moment JS today = moment().format(), // gets today's date timeSince = moment(today, 'YYYY-MM-DD').diff(moment(postedDate, 'YYYY-MM-DD'), 'days'); // sets up the dates to be compared so that we can get a number for if statement below if (timeSince >= 0) $this.text(moment(postedDate).fromNow()); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script> <div class="date" data-date="01 April 2018"></div> <div class="date " data-date="26 May 2018"></div> <div class="date" data-date="27 May 2018"></div> 

You're actually really close - you just need to implement the conditional logic based on timeSince being within the range you want, in your example 3 days.

If you simply switch your if statement with a ternary (or even an IF-ELSE) that checks to see if the timeSince value is less than or equal to 3, you can achieve the desired result. Here's the ternary statement to use in place of your current if one:

(timeSince <= 3) ? $this.text(moment(postedDate).fromNow()) : $this.text(moment(postedDate).format('MMM Do YY'));

The ternary/conditional statement first takes a condition to evaluate - in your case, whether or not timeSince is less than or equal to 3 days ago. If the condition is true, the first expression is executed - in this case, formatting the value from your .date selector using Moment's x ago format. If the condition is false, meaning more than 3 days ago in this example, it uses Moment to format the text using the MMM Do YY format.

Complete CodePen example here: https://codepen.io/anon/pen/zjgbmp

For an example of how a ternary helps keeps your code concise, here's the same solution using IF-ELSE :

  if (timeSince <= 3) {
    $this.text(moment(postedDate).fromNow());
  }
  else {
    $this.text(moment(postedDate).format('MMM Do YY'));
  }

We can acheive what you want by doing two things to your code first passing ing 'day' into the moment().diff() function to get the difference in days then checking that value is smaller than 3 using a ternary statement very similar to an if .

I've cleaned up the code abit to show the 5 steps i'm taking

  • Storing the time now outside the loop
  • get the date from the attribute
  • get the difference in days
  • format the date based on if its less than 3 days
  • appending that value to the element

 function formatDate() { const NOW = new Date(); $('.date').each(function() { const DATE = new Date($(this).data('date')); const DIFF = moment(NOW).diff(DATE, 'day'); const FORMAT = DIFF < 3 ? moment(DATE).fromNow() : moment(DATE).format('MMM Do YY'); $(this).text(FORMAT); }); } formatDate() 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script> <div class="date" data-date="01 April 2018"></div> <div class="date " data-date="26 May 2018"></div> <div class="date" data-date="27 May 2018"></div> 

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