Moment.js - завтра, сегодня и вчера

116

Хотелось бы moment().fromNow()функциональности, но когда дата близка, она слишком точна - напр. Я хочу, чтобы он отображался не «через 3 часа», а «сегодня» - так что в основном с «ежедневной» точностью.

Я пробовал использовать moment().calendar()функцию, она не форматируется, если разница дат больше 1 дня

Зиарно
источник

Ответы:

119

Вы также можете сделать это, чтобы получить дату на сегодня, завтра и вчера.

let today     = moment();

let tomorrow  = moment().add(1,'days');

let yesterday = moment().add(-1, 'days');
HussienK
источник
этого нет в официальном api! пожалуйста, предоставьте полифил, который у вас есть для этого
Халед Аль-Ансари
см. документацию здесь momentjs.com/docs/#/manipulating/add Единственное, что я добавляю, - это new Date()избежать предупреждения, которое библиотека продолжает выдавать мне (см. momentjs.com/docs/#/parsing/now )
HussienK
8
извините за голосование против, но я не об этом просил. Я удивлен, что это лучший ответ (на момент написания) ...
Зиарно
8
Это правда, я действительно добавил это как ссылку для себя и других, кто может оказаться здесь из-за того, как сформулирован заголовок вопроса. Похоже, это помогло многим людям, чему я рад. :)
HussienK
2
Является ли new Date()требуется? Я думал, moment()что в любом случае сгенерировал момент, используя сегодняшнюю дату
Крейг Майлз
37

Вы можете настроить способ отображения дат как .fromNowв .calendarметодах , так и в методах moment.updateLocale. Следующий код изменит способ .calendarотображения в соответствии с вопросом:

moment.updateLocale('en', {
    calendar : {
        lastDay : '[Yesterday]',
        sameDay : '[Today]',
        nextDay : '[Tomorrow]',
        lastWeek : '[Last] dddd',
        nextWeek : '[Next] dddd',
        sameElse : 'L'
    }
});

Исходя из вопроса, кажется, что этот .calendarметод был бы более подходящим - .fromNowхочет иметь префикс / суффикс прошлого / настоящего, но если вы хотите узнать больше, вы можете прочитать документацию на http://momentjs.com / документы / # / настройка / относительное время / .

Чтобы использовать это только в одном месте вместо перезаписи языковых стандартов, передайте строку по вашему выбору в качестве первого аргумента, когда вы определяете, moment.updateLocaleа затем вызываете метод календаря, используя этот языковой стандарт (например. moment.updateLocale('yesterday-today').calendar( /* moment() or whatever */ ))

РЕДАКТИРОВАТЬ: Moment ^ 2.12.0 теперь имеет updateLocaleметод. updateLocaleи localeкажутся функционально такими же, и localeеще не устарел, но обновили ответ, чтобы использовать более новый метод.

Свангордон
источник
1
это меняет глобальную локализацию, мне просто нужно это в
одном
См. Редактирование - вы можете создавать собственные языковые стандарты вместо перезаписи существующих
языков
35

Я использую комбинацию add()и endOf()с моментом

//...
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'
//...
гийомепотье
источник
21

Требования:

  • Когда дата находится дальше, используйте стандартный moment().fromNow()функционал.
  • Когда дата ближе, шоу "today", "yesterday", "tomorrow"и т.д.

Решение:

// 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. Начиная с версии 2.14.0, аргумент форматов функции календаря может быть обратным вызовом, см. Http://momentjs.com/docs/#/displaying/calendar-time/ .

Бен
источник
19

Вы можете использовать это:


const today     = moment();

const tomorrow  = moment().add(1, 'days');

const yesterday = moment().subtract(1, 'days');

Александр Егоров
источник
12

У меня есть аналогичное решение, но позволяет использовать локали:

    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'
Adara Hv
источник
он работает, но если вы измените '> = 1' на '> = 2', вы получите строку «вчера» вместо «1 день назад».
Dody
10

Начиная с версии 2.10.5, момент поддерживает указание форматов вывода календаря для каждого вызова. Более подробную информацию можно найти в документации Moment - Calendar .

**Moment 2.10.5**
moment().calendar(null, {
  sameDay: '[Today]',
  nextDay: '[Tomorrow]',
  nextWeek: 'dddd',
  lastDay: '[Yesterday]',
  lastWeek: '[Last] dddd',
  sameElse: 'DD/MM/YYYY'
});

Начиная с версии 2.14.0, календарь также может выполнять обратный вызов для возврата значений.

**Moment 2.14.0**
    moment().calendar(null, {
     sameDay: function (now) {
       if (this.isBefore(now)) {
         return '[Will Happen Today]';
       } else {
        return '[Happened Today]';
       }
       /* ... */
      }
    });
Правин
источник
почему отрицательные голоса? Дай мне знать, чтобы я мог улучшить этот
ответ
Это ответ.
oscarteg
Думаю, это правильный ответ. Но он по-прежнему не возвращает результат типа «3 дня назад», если он не настроен специально
Zortext
9

В Moment.js метод from () имеет ежедневную точность, которую вы ищете:

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"
тёрнт
источник
2
спасибо, но он по-прежнему не отображает «сегодня», а отображает ex. «1 день назад» вместо «вчера» - похоже, функциональность, которая мне нужна, должна быть индивидуализирована
Зиарно
1
fromдействительно не имеет ежедневной точности. Например, если вчера было четыре часа назад, и я выбрал время, которое было пять часов назад, вместо вчера будет сказано «5 часов назад». Это решение не имеет ничего общего с точностью from, но с указанными датами.
Майкл Миор,
5

Так вот что я в итоге сделал

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];
}
Зиарно
источник
У меня та же проблема, но мне нужно применить i18n, а у меня 10 языков ... так что я полагался на момент интернационализации JS ...
Chexpir
3

Вы можете использовать методы .add () и .subtract (), чтобы получить дату вчера и завтра. Затем используйте метод форматирования, чтобы получить только дату .format ("D / M / Y"), D означает день, M - месяц, Y - год. Проверить в 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");

Результат будет:

Current Milli - 1576693800000
today - 19/12/2019
tomorrow - 18/12/2019
yesterday - 18/12/2019
Ашутош
источник
3

Вот как я это делаю, используя момент :

  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();
Иффат
источник
1
const date = moment(YOUR_DATE)
return (moment().diff(date, 'days') >= 2) ? date.fromNow() : date.calendar().split(' ')[0]
Доди
источник