I'd like the moment().fromNow()
functionality, but when the date is close it is too precise - ex. I don't want it to show 'in 3 hours' but 'today' - so basically with a 'daily' precision.
I tried using the moment().calendar()
function, it doesn't format if the date difference is more than 1 day
This question is related to
javascript
date
momentjs
I have similar solution, but allows to use locales:
let date = moment(someDate);
if (moment().diff(date, 'days') >= 1) {
return date.fromNow(); // '2 days ago' etc.
}
return date.calendar().split(' ')[0]; // 'Today', 'yesterday', 'tomorrow'
Requirements:
moment().fromNow()
functionality."today"
, "yesterday"
, "tomorrow"
, etc.Solution:
// call this function, passing-in your date
function dateToFromNowDaily( myDate ) {
// get from-now for this date
var fromNow = moment( myDate ).fromNow();
// ensure the date is displayed with today and yesterday
return moment( myDate ).calendar( null, {
// when the date is closer, specify custom values
lastWeek: '[Last] dddd',
lastDay: '[Yesterday]',
sameDay: '[Today]',
nextDay: '[Tomorrow]',
nextWeek: 'dddd',
// when the date is further away, use from-now functionality
sameElse: function () {
return "[" + fromNow + "]";
}
});
}
NB: From version 2.14.0, the formats argument to the calendar function can be a callback, see http://momentjs.com/docs/#/displaying/calendar-time/.
From 2.10.5 moment supports specifying calendar output formats per invocation For a more detailed documentation check Moment - Calendar.
**Moment 2.10.5**
moment().calendar(null, {
sameDay: '[Today]',
nextDay: '[Tomorrow]',
nextWeek: 'dddd',
lastDay: '[Yesterday]',
lastWeek: '[Last] dddd',
sameElse: 'DD/MM/YYYY'
});
From 2.14.0 calendar can also take a callback to return values.
**Moment 2.14.0**
moment().calendar(null, {
sameDay: function (now) {
if (this.isBefore(now)) {
return '[Will Happen Today]';
} else {
return '[Happened Today]';
}
/* ... */
}
});
You can customize the way that both the .fromNow
and the .calendar
methods display dates using moment.updateLocale
. The following code will change the way that .calendar
displays as per the question:
moment.updateLocale('en', {
calendar : {
lastDay : '[Yesterday]',
sameDay : '[Today]',
nextDay : '[Tomorrow]',
lastWeek : '[Last] dddd',
nextWeek : '[Next] dddd',
sameElse : 'L'
}
});
Based on the question, it seems like the .calendar
method would be more appropriate -- .fromNow
wants to have a past/present prefix/suffix, but if you'd like to find out more you can read the documentation at http://momentjs.com/docs/#/customization/relative-time/.
To use this in only one place instead of overwriting the locales, pass a string of your choice as the first argument when you define the moment.updateLocale
and then invoke the calendar method using that locale (eg. moment.updateLocale('yesterday-today').calendar( /* moment() or whatever */ )
)
EDIT: Moment ^2.12.0 now has the updateLocale
method. updateLocale
and locale
appear to be functionally the same, and locale
isn't yet deprecated, but updated the answer to use the newer method.
You can use .add() and .subtract() method to get yesterday and tomorrow date. Then use format method to get only date .format("D/M/Y"), D stand for Day, M for Month, Y for Year. Check in Moment Docs
let currentMilli = Date.now()
let today = Moment(currentMilli).format("D/M/Y");
let tomorrow = Moment(currentMilli).add(1, 'days').format("D/M/Y");
let yesterday = Moment(currentMilli).subtract(1, 'days').format("D/M/Y");
Result will be:
Current Milli - 1576693800000
today - 19/12/2019
tomorrow - 18/12/2019
yesterday - 18/12/2019
So this is what I ended up doing
var dateText = moment(someDate).from(new Date());
var startOfToday = moment().startOf('day');
var startOfDate = moment(someDate).startOf('day');
var daysDiff = startOfDate.diff(startOfToday, 'days');
var days = {
'0': 'today',
'-1': 'yesterday',
'1': 'tomorrow'
};
if (Math.abs(daysDiff) <= 1) {
dateText = days[daysDiff];
}
You can also do this to get the date for today and tomorrow and yesterday
let today = moment();
let tomorrow = moment().add(1,'days');
let yesterday = moment().add(-1, 'days');
In Moment.js, the from() method has the daily precision you're looking for:
var today = new Date();
var tomorrow = new Date();
var yesterday = new Date();
tomorrow.setDate(today.getDate()+1);
yesterday.setDate(today.getDate()-1);
moment(today).from(moment(yesterday)); // "in a day"
moment(today).from(moment(tomorrow)); // "a day ago"
moment(yesterday).from(moment(tomorrow)); // "2 days ago"
moment(tomorrow).from(moment(yesterday)); // "in 2 days"
const date = moment(YOUR_DATE)
return (moment().diff(date, 'days') >= 2) ? date.fromNow() : date.calendar().split(' ')[0]
Here is how I do that using moment:
let today = moment().format('DD MMMM YYYY');
let tomorrow = moment().add(1, 'days').format('DD MMMM YYYY').toString();
let yesterday = moment().subtract(1, 'days').startOf('day').format('DD MMMM YYYY').toString();
You can use this:
const today = moment();
const tomorrow = moment().add(1, 'days');
const yesterday = moment().subtract(1, 'days');
I use a combination of add()
and endOf()
with moment
//...
const today = moment().endOf('day')
const tomorrow = moment().add(1, 'day').endOf('day')
if (date < today) return 'today'
if (date < tomorrow) return 'tomorrow'
return 'later'
//...
Source: Stackoverflow.com