Moment.js: mañana, hoy y ayer

115

Me gustaria el moment().fromNow() funcionalidad, pero cuando la fecha está cerca es demasiado precisa, por ejemplo. No quiero que se muestre "en 3 horas" sino "hoy", así que básicamente con una precisión "diaria".

Intenté usar la moment().calendar()función, no se formatea si la diferencia de fecha es más de 1 día

Ziarno
fuente

Respuestas:

119

También puede hacer esto para obtener la fecha de hoy, mañana y ayer.

let today     = moment();

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

let yesterday = moment().add(-1, 'days');
HussienK
fuente
¡esto no está en la API oficial! por favor proporcione el polyfill que tiene para esto
Khaled Al-Ansari
vea los documentos aquí momentjs.com/docs/#/manipulating/add Lo único que agrego es new Date()para evitar una advertencia que la biblioteca me sigue dando (ver momentjs.com/docs/#/parsing/now )
HussienK
8
perdón por el voto negativo, pero esto no es lo que pedí. Me sorprende que sea la respuesta más votada (al momento de escribir este artículo) ...
Ziarno
8
Es cierto, realmente lo agregué como referencia para mí y para otros que podrían terminar aquí debido a cómo está redactado el título de la pregunta. Parece que ayudó a mucha gente, por lo que estoy feliz. :)
HussienK
2
¿Es el new Date()requerido? Pensé que se moment()generó una instancia de momento usando la fecha de hoy de todos modos
Craig Myles
37

Puede personalizar la forma en que .fromNow los .calendarmétodos y los métodos muestran las fechas utilizando moment.updateLocale. El siguiente código cambiará la forma en que se .calendarmuestra según la pregunta:

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

Según la pregunta, parece que el .calendarmétodo sería más apropiado: .fromNowquiere tener un prefijo / sufijo pasado / presente, pero si desea obtener más información, puede leer la documentación en http://momentjs.com / docs / # / personalización / tiempo-relativo / .

Para usar esto en un solo lugar en lugar de sobrescribir las configuraciones regionales, pase una cadena de su elección como el primer argumento cuando defina moment.updateLocaley luego invoque el método de calendario usando esa configuración regional (por ejemplo moment.updateLocale('yesterday-today').calendar( /* moment() or whatever */ )) .

EDITAR: Momento ^ 2.12.0 ahora tiene el updateLocalemétodo. updateLocaley localeparecen ser funcionalmente iguales, y localeaún no están en desuso, pero actualizaron la respuesta para usar el método más nuevo.

Svangordon
fuente
1
esto cambia la localización global, solo necesito esto en 1 lugar :)
Ziarno
Ver editar: puede crear configuraciones regionales personalizadas en lugar de sobrescribir las configuraciones
regionales
35

Uso una combinación de add()y endOf()con 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'
//...
guillaumepotier
fuente
21

Requisitos:

  • Cuando la fecha esté más lejos, use el estándar moment().fromNow() funcionalidad .
  • Cuando la fecha está más cerca, muestran "today", "yesterday", "tomorrow", etc.

Solución:

// 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 de la versión 2.14.0, el argumento de formatos de la función de calendario puede ser una devolución de llamada, consulte http://momentjs.com/docs/#/displaying/calendar-time/ .

Ben
fuente
19

Puedes usar esto:


const today     = moment();

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

const yesterday = moment().subtract(1, 'days');
Alexandr Egorov
fuente
11

Tengo una solución similar, pero permite usar 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'
Adara Hv
fuente
funciona, pero si cambia '> = 1' por '> = 2', obtendrá la cadena 'ayer' en lugar de 'hace 1 día'.
Dody
10

A partir de la 2.10.5, el momento admite la especificación de formatos de salida de calendario por invocación. Para obtener una documentación más detallada, consulte Momento - Calendario .

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

Desde 2.14.0, el calendario también puede recibir una devolución de llamada para devolver valores.

**Moment 2.14.0**
    moment().calendar(null, {
     sameDay: function (now) {
       if (this.isBefore(now)) {
         return '[Will Happen Today]';
       } else {
        return '[Happened Today]';
       }
       /* ... */
      }
    });
pravin
fuente
¿Por qué los votos negativos? Avísame para que pueda mejorar esta
respuesta
Esta es la respuesta.
oscarteg
esta es la respuesta correcta, creo. Pero todavía no devuelve el resultado del tipo "hace 3 días" a menos que esté altamente personalizado
Zortext
9

En Moment.js, el método from () tiene la precisión diaria que está buscando:

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"
twernt
fuente
2
gracias, pero todavía no muestra "hoy" y muestra ex. 'Hace 1 día' en lugar de 'ayer' - parece que la funcionalidad que necesito debe ser personalizada
Ziarno
1
fromrealmente no tiene precisión diaria. Por ejemplo, si ayer fue hace cuatro horas y elijo una hora que fue hace cinco horas, dirá "hace cinco horas" en lugar de ayer. Esta solución no tiene nada que ver con la precisión de from, sino con las fechas pasadas.
Michael Mior
5

Entonces esto es lo que terminé haciendo

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];
}
Ziarno
fuente
Tengo el mismo problema, pero necesito aplicar i18n, y tengo 10 idiomas ... así que confiaba en el momento de internacionalización de JS ...
Chexpir
3

Puede usar el método .add () y .subtract () para obtener la fecha de ayer y mañana. Luego, use el método de formato para obtener solo la fecha .format ("D / M / Y"), D significa Día, M para Mes, Y para Año. Consultar 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");

El resultado será:

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

Así es como lo hago usando el 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();
Iffat
fuente
1
const date = moment(YOUR_DATE)
return (moment().diff(date, 'days') >= 2) ? date.fromNow() : date.calendar().split(' ')[0]
Dody
fuente