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

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');

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


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

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


19

Puedes usar esto:


const today     = moment();

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

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

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'

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]';
       }
       /* ... */
      }
    });

¿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"

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

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

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();

1
const date = moment(YOUR_DATE)
return (moment().diff(date, 'days') >= 2) ? date.fromNow() : date.calendar().split(' ')[0]
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.