Moment.js: domani, oggi e ieri


116

Vorrei la moment().fromNow()funzionalità, ma quando la data è vicina è troppo precisa - es. Non voglio che venga mostrato "tra 3 ore" ma "oggi", quindi fondamentalmente con una precisione "quotidiana".

Ho provato a utilizzare la moment().calendar()funzione, non si formatta se la differenza di data è superiore a 1 giorno

Risposte:


120

Puoi anche farlo per ottenere la data per oggi, domani e ieri

let today     = moment();

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

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

questo non è nell'API ufficiale! per favore fornisci il polyfill che hai per questo
Khaled Al-Ansari

vedi i documenti qui momentjs.com/docs/#/manipulating/add L'unica cosa che aggiungo è new Date()per evitare un avviso che la libreria continua a darmi (vedi momentjs.com/docs/#/parsing/now )
HussienK

8
scusa per il voto negativo, ma non è quello che ho chiesto. Sono sorpreso che sia la risposta più votata (al momento in cui scrivo) ...
Ziarno

8
È vero, l'ho aggiunto davvero come riferimento per me e per altri che potrebbero finire qui a causa di come è formulato il titolo della domanda. Sembra che abbia aiutato molte persone, cosa di cui sono felice. :)
HussienK

2
È new Date()richiesto? Pensavo comunque di aver moment()generato un'istanza del momento utilizzando la data odierna
Craig Myles,

37

È possibile personalizzare il modo in cui entrambi .fromNowi .calendarmetodi visualizzano le date utilizzando moment.updateLocale. Il codice seguente cambierà il modo in cui .calendarviene visualizzato come da domanda:

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

Sulla base della domanda, sembra che il .calendarmetodo sarebbe più appropriato: .fromNowvuole avere un prefisso / suffisso passato / presente, ma se vuoi saperne di più puoi leggere la documentazione su http://momentjs.com / docs / # / personalizzazione / relative-time / .

Per usarlo in un solo posto invece di sovrascrivere le impostazioni locali, passa una stringa di tua scelta come primo argomento quando definisci il moment.updateLocalee poi invoca il metodo del calendario usando quella locale (es. moment.updateLocale('yesterday-today').calendar( /* moment() or whatever */ ))

EDIT: Moment ^ 2.12.0 ora ha il updateLocalemetodo. updateLocalee localesembrano essere funzionalmente uguali e localenon è ancora deprecato, ma ha aggiornato la risposta per utilizzare il metodo più recente.


1
questo cambia la localizzazione globale, mi serve solo questo in 1 posto :)
Ziarno

Vedi modifica: puoi creare impostazioni locali personalizzate invece di sovrascrivere le impostazioni locali esistenti
svangordon

35

Uso una combinazione di add()e 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

Requisiti:

  • Quando la data è più lontana, utilizzare la moment().fromNow()funzionalità standard .
  • Quando la data è più vicino, spettacolo "today", "yesterday", "tomorrow", etc.

Soluzione:

// 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: Dalla versione 2.14.0, l'argomento dei formati della funzione calendario può essere un callback, vedere http://momentjs.com/docs/#/displaying/calendar-time/ .


19

Puoi usare questo:


const today     = moment();

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

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

11

Ho una soluzione simile, ma consente di utilizzare le impostazioni locali:

    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'

funziona, ma se cambi "> = 1" per "> = 2" otterrai la stringa "ieri" invece di "1 giorno fa".
Dody

10

Da 2.10.5 moment supporta la specifica dei formati di output del calendario per invocazione. Per una documentazione più dettagliata, controllare Moment - Calendar .

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

Dalla 2.14.0 il calendario può anche richiedere una richiamata per restituire i valori.

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

perché i voti negativi? Fammi sapere in modo che possa migliorare questo ans
pravin

Questa è la risposta.
oscarteg

questa è la risposta corretta credo. Ma non restituisce ancora il risultato di tipo "3 giorni fa" a meno che non sia altamente personalizzato
Zortext

9

In Moment.js, il metodo from () ha la precisione quotidiana che stai cercando:

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
grazie, ma ancora non viene visualizzato "oggi" e viene visualizzato ex. "1 giorno fa" invece di "ieri" - sembra che la funzionalità di cui ho bisogno debba essere personalizzata
Ziarno

1
fromnon ha una precisione quotidiana. Ad esempio, se ieri è stato quattro ore fa e scelgo un'ora che è stata cinque ore fa, verrà visualizzato "5 ore fa" invece di ieri. Questa soluzione non ha nulla a che fare con la precisione di from, ma delle date trascorse.
Michael Mior

5

Quindi questo è quello che ho finito per fare

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

Ho lo stesso problema, ma devo applicare i18n e ho 10 lingue ... quindi facevo affidamento sull'internazionalizzazione momentJS ...
Chexpir

3

Puoi usare i metodi .add () e .subtract () per ottenere la data di ieri e di domani. Quindi utilizza il metodo di formattazione per ottenere solo la data .format ("G / M / A"), D sta per giorno, M per mese, Y per anno. Controlla 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");

Il risultato sarà:

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

3

Ecco come lo faccio usando il 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]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.