Moment.js - amanhã, hoje e ontem


115

Eu gostaria da moment().fromNow()funcionalidade, mas quando a data está próxima é muito precisa - ex. Eu não quero mostrar 'em 3 horas', mas 'hoje' - basicamente com uma precisão 'diária'.

Tentei usar a moment().calendar()função, ela não formata se a diferença de data for maior que 1 dia

Respostas:


119

Você também pode fazer isso para obter a data de hoje, amanhã e ontem

let today     = moment();

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

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

isso não está na api oficial! forneça o polyfill que você tem para isso
Khaled Al-Ansari

veja os documentos aqui momentjs.com/docs/#/manipulating/add A única coisa que adiciono é o new Date()para evitar um aviso que a lib continua me dando (veja momentjs.com/docs/#/parsing/now )
HussienK

8
desculpe pelo voto negativo, mas não foi isso que eu pedi. Estou surpreso que seja a resposta mais votada (no momento da escrita) ...
Ziarno

8
É verdade, eu realmente adicionei isso como uma referência para mim e outras pessoas que podem acabar aqui por causa da forma como o título da pergunta está formulado. Parece que ajudou muita gente, o que me deixa feliz. :)
HussienK

2
É new Date()necessário? Achei que tivesse moment()gerado uma instância de momento usando a data de hoje de qualquer maneira
Craig Myles

37

Você pode personalizar a maneira como .fromNowos .calendarmétodos e exibem as datas usando moment.updateLocale. O código a seguir mudará a forma de .calendarexibição de acordo com a pergunta:

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

Com base na pergunta, parece que o .calendarmétodo seria mais apropriado - .fromNowdeseja ter um prefixo / sufixo passado / presente, mas se quiser saber mais, leia a documentação em http://momentjs.com / docs / # / customization / relative-time / .

Para usar isso em apenas um lugar em vez de substituir as localidades, passe uma string de sua escolha como o primeiro argumento ao definir o moment.updateLocalee, em seguida, invoque o método de calendário usando aquela localidade (por exemplo. moment.updateLocale('yesterday-today').calendar( /* moment() or whatever */ ))

EDIT: Moment ^ 2.12.0 agora tem o updateLocalemétodo. updateLocalee localeparecem ter a mesma funcionalidade e localeainda não estão obsoletos, mas atualizaram a resposta para usar o método mais recente.


1
isso muda a localização global, só preciso disso em um lugar :)
Ziarno

Veja editar - você pode criar localidades personalizadas em vez de substituir localidades existentes
svangordon

35

Eu uso uma combinação de add()e endOf()com momento

//...
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

Requisitos:

  • Quando a data estiver mais distante, use a moment().fromNow()funcionalidade padrão .
  • Quando a data se aproxima, mostrar "today", "yesterday", "tomorrow", etc.

Solução:

// 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: a partir da versão 2.14.0, o argumento de formatos para a função de calendário pode ser um retorno de chamada, consulte http://momentjs.com/docs/#/displaying/calendar-time/ .


19

Você pode usar isto:


const today     = moment();

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

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

11

Tenho solução semelhante, mas permite usar localidades:

    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'

funciona, mas se você alterar '> = 1' para '> = 2', você obterá a string 'ontem' em vez de '1 dia atrás'.
Dody

10

A partir de 2.10.5, o momento suporta a especificação de formatos de saída de calendário por chamada. Para uma documentação mais detalhada, verifique Momento - Calendário .

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

De 2.14.0, o calendário também pode receber uma chamada de retorno para retornar valores.

**Moment 2.14.0**
    moment().calendar(null, {
     sameDay: function (now) {
       if (this.isBefore(now)) {
         return '[Will Happen Today]';
       } else {
        return '[Happened Today]';
       }
       /* ... */
      }
    });

por que os votos negativos? Deixe-me saber para que eu possa melhorar esta ans
pravin

Esta é a resposta.
oscarteg

esta é a resposta correta, eu acho. Mas ainda não retorna o resultado do tipo "3 dias atrás", a menos que seja altamente personalizado
Zortext

9

Em Moment.js, o método from () tem a precisão diária que você está procurando:

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
obrigado, mas ainda não exibe 'hoje' e exibe ex. '1 dia atrás' em vez de 'ontem' - parece que a funcionalidade de que preciso precisa ser personalizada
Ziarno

1
fromrealmente não tem precisão diária. Por exemplo, se ontem foi há quatro horas e eu escolher um horário que foi há cinco horas, dirá "5 horas atrás" em vez de ontem. Esta solução não tem nada a ver com a precisão de from, mas com as datas passadas.
Michael Mior

5

Então foi isso que acabei fazendo

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];
}

Tenho o mesmo problema, mas preciso aplicar i18n, e tenho 10 idiomas ... então estava contando com o momento de internacionalização do JS ...
Chexpir

3

Você pode usar os métodos .add () e .subtract () para obter a data de ontem e amanhã. Em seguida, use o método de formatação para obter apenas a data .formatar ("D / M / A"), D significa Dia, M para Mês, A para Ano. Verificar no 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");

O resultado será:

Current Milli - 1576693800000
today - 19/12/2019
tomorrow - 18/12/2019
yesterday - 18/12/2019

3

Aqui está como faço isso usando o momento :

  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]
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.