Moment.js - พรุ่งนี้วันนี้และเมื่อวาน


117

ฉันต้องการmoment().fromNow()ฟังก์ชั่นการใช้งาน แต่เมื่อปิดวันที่นั้นแม่นยำเกินไปเช่น ฉันไม่ต้องการให้แสดง 'ใน 3 ชั่วโมง' แต่ 'วันนี้' - โดยพื้นฐานแล้วมีความแม่นยำ 'รายวัน'

ฉันลองใช้moment().calendar()ฟังก์ชั่นมันไม่ได้จัดรูปแบบหากความแตกต่างของวันที่มากกว่า 1 วัน

คำตอบ:


120

คุณสามารถทำได้เพื่อรับวันที่สำหรับวันนี้และพรุ่งนี้และเมื่อวานนี้

let today     = moment();

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

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

นี่ไม่ได้อยู่ใน API อย่างเป็นทางการ! โปรดระบุ polyfill ที่คุณมีสำหรับสิ่งนี้
Khaled Al-Ansari

ดูเอกสารที่นี่momentjs.com/docs/#/manipulating/addสิ่งเดียวที่ฉันเพิ่มคือการnew Date()หลีกเลี่ยงคำเตือนที่ lib ให้ฉัน (ดูmomentjs.com/docs/#/parsing/now )
HussienK

8
ขออภัยสำหรับการโหวตที่ลดลง แต่นี่ไม่ใช่สิ่งที่ฉันขอ ฉันแปลกใจที่เป็นคำตอบที่ได้รับการโหวตสูงสุด (ในขณะที่เขียน) ...
Ziarno

8
เป็นเรื่องจริงฉันได้เพิ่มไว้เป็นข้อมูลอ้างอิงสำหรับตัวเองและคนอื่น ๆ ที่อาจจะจบลงที่นี่เนื่องจากชื่อของคำถามเป็นวลี ดูเหมือนว่ามันช่วยคนได้มากซึ่งฉันก็มีความสุข :)
HussienK

2
เป็นnew Date()ต้อง? ฉันคิดว่าmoment()สร้างช่วงเวลาหนึ่งขึ้นโดยใช้วันที่ของวันนี้อยู่ดี
Craig Myles

37

คุณสามารถกำหนดวิธีการที่ทั้งสอง.fromNowและวิธีการแสดงวันที่ใช้.calendar moment.updateLocaleรหัสต่อไปนี้จะเปลี่ยนวิธีการ.calendarแสดงตามคำถาม:

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

จากคำถามดูเหมือนว่า.calendarวิธีการนี้จะเหมาะสมกว่า - .fromNowต้องการมีคำนำหน้า / คำต่อท้ายในอดีต / ปัจจุบัน แต่ถ้าคุณต้องการทราบข้อมูลเพิ่มเติมคุณสามารถอ่านเอกสารได้ที่http://momentjs.com / docs / # / การปรับแต่ง / เวลาสัมพัทธ์ / .

ในการใช้สิ่งนี้ในที่เดียวแทนที่จะเขียนทับโลแคลให้ส่งสตริงที่คุณเลือกเป็นอาร์กิวเมนต์แรกเมื่อคุณกำหนดmoment.updateLocaleและเรียกใช้เมธอดปฏิทินโดยใช้โลแคลนั้น (เช่นmoment.updateLocale('yesterday-today').calendar( /* moment() or whatever */ ))

แก้ไข: Moment ^ 2.12.0 มีupdateLocaleวิธีการแล้ว updateLocaleและlocaleดูเหมือนจะใช้งานได้เหมือนเดิมและlocaleยังไม่ได้เลิกใช้งาน แต่อัปเดตคำตอบเพื่อใช้วิธีที่ใหม่กว่า


1
สิ่งนี้เปลี่ยนการแปลทั่วโลกฉันต้องการสิ่งนี้ในที่
Ziarno

ดูการแก้ไข - คุณสามารถสร้างภาษาที่กำหนดเองแทนการเขียนทับภาษาที่มีอยู่ได้
svangordon

35

ฉันใช้การผสมผสานระหว่างadd()และendOf()กับช่วงเวลา

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

22

ข้อกำหนด:

  • เมื่อวันที่ห่างออกไปให้ใช้moment().fromNow()ฟังก์ชันมาตรฐาน
  • เมื่อวันที่อยู่ใกล้ชิด, การแสดง"today", "yesterday", "tomorrow"ฯลฯ

สารละลาย:

// 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 + "]";
        }
    });
}

หมายเหตุ: จากเวอร์ชั่น 2.14.0 อาร์กิวเมนต์รูปแบบฟังก์ชั่นปฏิทินที่สามารถเรียกกลับดูhttp://momentjs.com/docs/#/displaying/calendar-time/



12

ฉันมีวิธีแก้ปัญหาที่คล้ายกัน แต่อนุญาตให้ใช้สถานที่:

    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'

มันใช้งานได้ แต่ถ้าคุณเปลี่ยน '> = 1' for '> = 2' คุณจะได้รับสตริง 'เมื่อวาน' แทน '1 วันที่แล้ว'
Dody

10

จากช่วงเวลา 2.10.5 สนับสนุนการระบุรูปแบบการออกปฏิทินต่อการภาวนาสำหรับรายละเอียดเพิ่มเติมเอกสารการตรวจสอบช่วงเวลา - ปฏิทิน

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

จากปฏิทิน 2.14.0 ยังสามารถโทรกลับเพื่อส่งคืนค่า

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

ทำไมถึงโหวตลง? แจ้งให้เราทราบเพื่อปรับปรุง ans นี้
pravin

นี่คือคำตอบ
oscarteg

นี่คือคำตอบที่ถูกต้องที่ฉันคิด แต่ก็ยังไม่ส่งคืนผลลัพธ์ประเภท "3 วันที่แล้ว" เว้นแต่จะมีการปรับแต่งสูง
Zortext

9

ใน Moment.js เมธอดfrom ()มีความแม่นยำรายวันที่คุณต้องการ:

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
ขอบคุณ แต่มันยังไม่แสดง 'วันนี้' และแสดงเช่น '1 วันที่แล้ว' แทนที่จะเป็น 'เมื่อวาน' - ดูเหมือนว่าฟังก์ชันที่ฉันต้องการจะต้องกำหนดเอง
Ziarno

1
fromไม่มีความแม่นยำรายวันจริงๆ ตัวอย่างเช่นถ้าเมื่อวานนี้เป็นเวลาสี่ชั่วโมงที่แล้วและฉันเลือกเวลาที่เป็นเวลาห้าชั่วโมงที่แล้วระบบจะพูดว่า "5 ชั่วโมงที่แล้ว" แทนเมื่อวานนี้ โซลูชันนี้ไม่เกี่ยวข้องกับความแม่นยำfromแต่เป็นวันที่ที่ผ่านไป
Michael Mior

5

นี่คือสิ่งที่ฉันทำ

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

ฉันมีปัญหาเดียวกัน แต่ฉันต้องใช้ i18n และฉันมี 10 ภาษา ... ดังนั้นฉันจึงอาศัยช่วงเวลาสากลของ JS ...
Chexpir

3

คุณสามารถใช้เมธอด. add () และ. subtract () เพื่อรับวันที่เมื่อวานและวันพรุ่งนี้ จากนั้นใช้วิธีการจัดรูปแบบเพื่อรับเฉพาะวันที่. รูปแบบ ("D / M / Y"), D ย่อมาจากวัน, M สำหรับเดือน, Y สำหรับปี ตรวจสอบใน 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");

ผลลัพธ์จะเป็น:

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

3

นี่คือวิธีที่ฉันทำโดยใช้ช่วงเวลา :

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.