Moment.js - jutro, dziś i wczoraj

116

Chciałbym moment().fromNow() funkcjonalność, ale kiedy zbliża się termin, jest zbyt precyzyjny - np. Nie chcę, żeby wyświetlało się „za 3 godziny”, ale „dzisiaj” - czyli w zasadzie z „codzienną” precyzją.

Próbowałem użyć tej moment().calendar()funkcji, nie formatuje, jeśli różnica dat jest większa niż 1 dzień

Ziarno
źródło

Odpowiedzi:

120

Możesz to również zrobić, aby uzyskać datę na dziś, jutro i wczoraj

let today     = moment();

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

let yesterday = moment().add(-1, 'days');
HussienK
źródło
tego nie ma w oficjalnym api! proszę podać wypełnienie, które masz do tego
Khaled Al-Ansari
zobacz dokumentację tutaj momentjs.com/docs/#/manipulating/add Jedyną rzeczą, którą dodam, jest new Date()uniknięcie ostrzeżenia, które wyświetla mi biblioteka (patrz momentjs.com/docs/#/parsing/now )
HussienK
8
przepraszam za głosowanie przeciw, ale nie o to prosiłem. Dziwię się, że jest to najczęściej głosowana odpowiedź (w momencie pisania) ...
Ziarno,
8
To prawda, naprawdę dodałem to jako odniesienie dla siebie i innych, którzy mogą tu trafić ze względu na sposób sformułowania tytułu pytania. Wygląda na to, że pomogło to wielu ludziom, z czego jestem zadowolony. :)
HussienK
2
Czy jest to new Date()wymagane? Pomyślałem, że i tak moment()wygenerowałem moment przy użyciu dzisiejszej daty
Craig Myles
37

Możesz dostosować sposób, w jaki obie metody .fromNowi .calendarmetody wyświetlają daty przy użyciu moment.updateLocale. Poniższy kod zmieni sposób .calendarwyświetlania zgodnie z pytaniem:

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

Na podstawie pytania wydaje się, że .calendarmetoda byłaby bardziej odpowiednia - .fromNowchce mieć poprzedni / obecny prefiks / sufiks, ale jeśli chcesz dowiedzieć się więcej, możesz przeczytać dokumentację na http://momentjs.com / docs / # / customization / względny czas / .

Aby użyć tego tylko w jednym miejscu, zamiast nadpisywać ustawienia regionalne, przekaż wybrany przez siebie ciąg jako pierwszy argument podczas definiowania, moment.updateLocalea następnie wywołaj metodę kalendarza przy użyciu tych ustawień regionalnych (np. moment.updateLocale('yesterday-today').calendar( /* moment() or whatever */ ))

EDYCJA: Moment ^ 2.12.0 ma teraz updateLocalemetodę. updateLocalei localewydają się funkcjonalnie takie same i localenie są jeszcze przestarzałe, ale zaktualizowałem odpowiedź, aby używać nowszej metody.

svangordon
źródło
1
to zmienia globalną lokalizację, po prostu potrzebuję tego w 1 miejscu :)
Ziarno
Zobacz edycję - możesz tworzyć własne ustawienia regionalne zamiast nadpisywać istniejące
svangordon
35

Używam kombinacji add()i endOf()chwili

//...
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
źródło
21

Wymagania:

  • Gdy data jest dalej, skorzystaj ze standardowej moment().fromNow()funkcjonalności.
  • Jeżeli data jest bliżej, show "today", "yesterday", "tomorrow", itd.

Rozwiązanie:

// 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: Od wersji 2.14.0 argument formatów funkcji kalendarza może być wywołaniem zwrotnym, patrz http://momentjs.com/docs/#/displaying/calendar-time/ .

Ben
źródło
19

Możesz użyć tego:


const today     = moment();

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

const yesterday = moment().subtract(1, 'days');
Alexandr Egorov
źródło
12

Mam podobne rozwiązanie, ale pozwala na użycie lokalizacji:

    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
źródło
to działa, ale jeśli zmienisz „> = 1” na „> = 2”, otrzymasz ciąg „wczoraj” zamiast „1 dzień temu”.
Dody
10

Od 2.10.5 moment obsługuje określanie formatów wyjściowych kalendarza na wywołanie. Aby uzyskać bardziej szczegółową dokumentację, sprawdź Moment - Kalendarz .

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

Od 2.14.0 kalendarz może również przyjmować wywołanie zwrotne w celu zwrócenia wartości.

**Moment 2.14.0**
    moment().calendar(null, {
     sameDay: function (now) {
       if (this.isBefore(now)) {
         return '[Will Happen Today]';
       } else {
        return '[Happened Today]';
       }
       /* ... */
      }
    });
pravin
źródło
dlaczego głosy przeciw? Niech mi więc wiem, że mogę poprawić ten ans
Pravin
To jest odpowiedź.
oscarteg
myślę, że to jest poprawna odpowiedź. Ale nadal nie zwraca wyniku typu „3 dni temu”, chyba że jest wysoce dostosowany
Zortext
9

W Moment.js metoda from () ma codzienną precyzję, której szukasz:

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
źródło
2
dzięki, ale nadal nie wyświetla „dzisiaj” i wyświetla np. „1 dzień temu” zamiast „wczoraj” - wygląda na to, że potrzebna mi funkcjonalność ma być niestandardowa
Ziarno
1
fromtak naprawdę nie ma codziennej precyzji. Na przykład, jeśli wczoraj było cztery godziny temu i wybiorę godzinę sprzed pięciu godzin, zamiast wczoraj zostanie wyświetlone „5 godzin temu”. To rozwiązanie nie ma nic wspólnego z precyzją from, ale z
podanymi
5

Więc to właśnie zrobiłem

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
źródło
Mam ten sam problem, ale muszę zastosować i18n, a mam 10 języków ... więc polegałem na momencie umiędzynarodowieniaJS ...
Chexpir
3

Możesz użyć metod .add () i .subtract (), aby uzyskać datę wczorajszą i jutrzejszą. Następnie użyj metody formatowania, aby uzyskać tylko format daty („D / M / R”), D oznacza dzień, M - miesiąc, Y - rok. Sprawdź w 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");

Wynik będzie:

Current Milli - 1576693800000
today - 19/12/2019
tomorrow - 18/12/2019
yesterday - 18/12/2019
Ashutosh
źródło
3

Oto jak to robię za pomocą momentu :

  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
źródło
1
const date = moment(YOUR_DATE)
return (moment().diff(date, 'days') >= 2) ? date.fromNow() : date.calendar().split(' ')[0]
Dody
źródło