วิธีจัดรูปแบบเวลาตั้งแต่ xxx เช่น“ 4 นาทีก่อน” คล้ายกับไซต์ Stack Exchange


210

คำถามคือวิธีการจัดรูปแบบ JavaScript Dateเป็นสตริงที่ระบุเวลาที่ผ่านไปคล้ายกับวิธีที่คุณเห็นเวลาที่แสดงใน Stack Overflow

เช่น

  • 1 นาทีที่แล้ว
  • 1 ชั่วโมงที่แล้ว
  • 1 วันที่แล้ว
  • 1 เดือนที่แล้ว
  • 1 ปีที่ผ่านมา



มีประโยชน์สำหรับสิ่งนี้: Intl.RelativeTimeFormat.prototype.format().
КонстантинВан

คำตอบ:


324

function timeSince(date) {

  var seconds = Math.floor((new Date() - date) / 1000);

  var interval = Math.floor(seconds / 31536000);

  if (interval > 1) {
    return interval + " years";
  }
  interval = Math.floor(seconds / 2592000);
  if (interval > 1) {
    return interval + " months";
  }
  interval = Math.floor(seconds / 86400);
  if (interval > 1) {
    return interval + " days";
  }
  interval = Math.floor(seconds / 3600);
  if (interval > 1) {
    return interval + " hours";
  }
  interval = Math.floor(seconds / 60);
  if (interval > 1) {
    return interval + " minutes";
  }
  return Math.floor(seconds) + " seconds";
}
var aDay = 24*60*60*1000;
console.log(timeSince(new Date(Date.now()-aDay)));
console.log(timeSince(new Date(Date.now()-aDay*2)));


3
@hello - ใช่จุดออกเดียวมีคุณธรรมเมื่อไม่ได้รับในทาง สิ่งที่ถือว่าเป็นเรื่องจริงจังในปัจจุบันนี้คือความเข้าใจผิดที่มาของคติพจน์
Sky Sanders

36
ฟังก์ชั่นที่ดี แต่ข้อสังเกตบางส่วน เปลี่ยนบรรทัดแรกเป็น: var วินาที = Math.floor ((วันที่ใหม่ (). getTime () / 1,000) - วันที่)) เพื่อทำงานกับ unix timestamps และจำเป็นต้องเปลี่ยนช่วงเวลา> 1 เป็น intval> = 1 มิฉะนั้นจะแสดงสิ่งต่าง ๆ เช่น 75 นาที (ระหว่าง 1 ถึง 2 ชั่วโมง)
PanMan

3
@PanMan หากคุณเพิ่งเปลี่ยน> เป็น> = คุณจะสิ้นสุดด้วยเวลาเช่น "1 นาที" ฉันโพสต์เวอร์ชันที่แก้ไขแล้วของคำตอบนี้ซึ่งเพิ่ม "s": stackoverflow.com/a/23259289/373655 โดยมีเงื่อนไข
rob

ไม่เคยใช้สตริง แต่ String.format ถ้าคุณต้องการวิธีการแก้ปัญหาที่สามารถสากล
RDS

ถ้าฉันต้องการวางไว้ในชั้น div ฉันจะทำอย่างไร ขออภัยฉันไม่ใช่มืออาชีพใน javascript ฉันลองใช้ document.getElementsByTagName ('. sampleclass') [0] .innerHTML = timeSince (date); และ document.getElementById นี้ ('idname') [0] .innerHTML = timeSince (date); แต่มันไม่ทำงาน ความช่วยเหลือใด ๆ ขอบคุณ.
x'tian

119

อาจเป็น overkill ในกรณีนี้ แต่ถ้าโอกาสแสดงmoment.jsนั้นยอดเยี่ยมมาก!

Moment.js เป็นไลบรารี datavascript ของ javascript หากต้องการใช้สำหรับสถานการณ์ดังกล่าวคุณจะต้อง:

moment(yourdate).fromNow()

http://momentjs.com/docs/#/displaying/fromnow/

ภาคผนวก 2018 : Luxonเป็นห้องสมุดที่ทันสมัยแห่งใหม่


สวัสดีฉันใช้คำตอบของคุณในการหาเวลา differene ฉันจะทำอย่างไรถ้าฉันต้องการตัวอักษรตัวแรกของปีดาต้าเหมือนปี y เดือนและเดือนและวันเป็น d?
Nodirabegimxonoyim

57

ฉันยังไม่ได้ตรวจสอบ (แม้ว่ามันจะไม่เป็นเรื่องยากที่จะ) แต่ผมคิดว่าเว็บไซต์ Stack แลกเปลี่ยนใช้jquery.timeagoปลั๊กอินเพื่อสร้างสตริงเวลาเหล่านี้


มันค่อนข้างง่ายในการใช้ปลั๊กอินและทำความสะอาดและอัปเดตโดยอัตโนมัติ

นี่คือตัวอย่างรวดเร็ว (จากหน้าแรกของปลั๊กอิน):

ก่อนอื่นให้โหลด jQuery และปลั๊กอิน:

<script src="jquery.min.js" type="text/javascript"></script> <script src="jquery.timeago.js" type="text/javascript"></script>

ทีนี้มาแนบไฟล์นี้กับ timestamps ของคุณบน DOM แล้ว

jQuery(document).ready(function() {
jQuery("abbr.timeago").timeago(); });

สิ่งนี้จะเปลี่ยนabbrองค์ประกอบทั้งหมดด้วยคลาสtimeagoและการประทับเวลา ISO 8601 ในชื่อ: <abbr class="timeago" title="2008-07-17T09:24:17Z">July 17, 2008</abbr>เป็นบางสิ่งเช่นนี้: <abbr class="timeago" title="July 17, 2008">about a year ago</abbr>ซึ่งให้ผล: ประมาณหนึ่งปีที่แล้ว เมื่อเวลาผ่านไปการประทับเวลาจะอัปเดตโดยอัตโนมัติ


11
ไม่ใช่ทุกคนที่ใช้ JQuery

2
ไม่มีเหตุผลที่จะใช้สิ่งนี้เป็นปลั๊กอิน jquery
AlexG

57

สิ่งนี้จะแสดงรูปแบบเวลาในอดีตและก่อนหน้าเช่น '2 วันที่ผ่านมา' '10 นาทีนับจากนี้ 'และคุณสามารถผ่านวัตถุวันที่, เวลาประทับที่เป็นตัวเลขหรือสตริงวันที่ได้

function time_ago(time) {

  switch (typeof time) {
    case 'number':
      break;
    case 'string':
      time = +new Date(time);
      break;
    case 'object':
      if (time.constructor === Date) time = time.getTime();
      break;
    default:
      time = +new Date();
  }
  var time_formats = [
    [60, 'seconds', 1], // 60
    [120, '1 minute ago', '1 minute from now'], // 60*2
    [3600, 'minutes', 60], // 60*60, 60
    [7200, '1 hour ago', '1 hour from now'], // 60*60*2
    [86400, 'hours', 3600], // 60*60*24, 60*60
    [172800, 'Yesterday', 'Tomorrow'], // 60*60*24*2
    [604800, 'days', 86400], // 60*60*24*7, 60*60*24
    [1209600, 'Last week', 'Next week'], // 60*60*24*7*4*2
    [2419200, 'weeks', 604800], // 60*60*24*7*4, 60*60*24*7
    [4838400, 'Last month', 'Next month'], // 60*60*24*7*4*2
    [29030400, 'months', 2419200], // 60*60*24*7*4*12, 60*60*24*7*4
    [58060800, 'Last year', 'Next year'], // 60*60*24*7*4*12*2
    [2903040000, 'years', 29030400], // 60*60*24*7*4*12*100, 60*60*24*7*4*12
    [5806080000, 'Last century', 'Next century'], // 60*60*24*7*4*12*100*2
    [58060800000, 'centuries', 2903040000] // 60*60*24*7*4*12*100*20, 60*60*24*7*4*12*100
  ];
  var seconds = (+new Date() - time) / 1000,
    token = 'ago',
    list_choice = 1;

  if (seconds == 0) {
    return 'Just now'
  }
  if (seconds < 0) {
    seconds = Math.abs(seconds);
    token = 'from now';
    list_choice = 2;
  }
  var i = 0,
    format;
  while (format = time_formats[i++])
    if (seconds < format[0]) {
      if (typeof format[2] == 'string')
        return format[list_choice];
      else
        return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token;
    }
  return time;
}

var aDay = 24 * 60 * 60 * 1000;
console.log(time_ago(new Date(Date.now() - aDay)));
console.log(time_ago(new Date(Date.now() - aDay * 2)));


แทนที่บรรทัดสุดท้ายreturn time;ด้วยformat = time_formats[time_formats.length - 1]; return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token;เพื่อคืนค่าศตวรรษเป็นช่วงเวลานานแทนที่จะเป็นมิลลิวินาที
Aquila Sands

ดีมาก! แม้ว่าฉันจะสังเกตเห็นใน iOS เมื่อใช้กับตัวกรองเชิงมุมเบราว์เซอร์จะส่งคืน NaN ที่นี่ วิธีนี้แก้ไขได้: time = + new Date (time.replace (/ - / g, '/'));
Tiago

เยี่ยมมาก แต่การมอบหมายในขณะนั้นเป็นสิ่งที่น่าเกลียดและสับสน การเปลี่ยนเป็นลูป forEach จะดีกว่า
Martin Dawson

25

นี่คือการแก้ไขเล็กน้อยในโซลูชันของ Sky Sander ที่อนุญาตให้วันที่ที่จะป้อนเป็นสตริงและสามารถแสดงช่วงเช่น "1 นาที" แทนที่จะเป็น "73 วินาที"

var timeSince = function(date) {
  if (typeof date !== 'object') {
    date = new Date(date);
  }

  var seconds = Math.floor((new Date() - date) / 1000);
  var intervalType;

  var interval = Math.floor(seconds / 31536000);
  if (interval >= 1) {
    intervalType = 'year';
  } else {
    interval = Math.floor(seconds / 2592000);
    if (interval >= 1) {
      intervalType = 'month';
    } else {
      interval = Math.floor(seconds / 86400);
      if (interval >= 1) {
        intervalType = 'day';
      } else {
        interval = Math.floor(seconds / 3600);
        if (interval >= 1) {
          intervalType = "hour";
        } else {
          interval = Math.floor(seconds / 60);
          if (interval >= 1) {
            intervalType = "minute";
          } else {
            interval = seconds;
            intervalType = "second";
          }
        }
      }
    }
  }

  if (interval > 1 || interval === 0) {
    intervalType += 's';
  }

  return interval + ' ' + intervalType;
};
var aDay = 24 * 60 * 60 * 1000;
console.log(timeSince(new Date(Date.now() - aDay)));
console.log(timeSince(new Date(Date.now() - aDay * 2)));


2
นี้ไม่ได้ทำงานให้กับวินาทีเป็นช่วงเวลาที่เหลือเป็น 0 interval = Math.floor(seconds / 60);จาก ฉันเพิ่มinterval = seconds;เข้าไปในรอบสุดท้ายelseและมันก็ใช้ได้ดี
howard10

2
หากช่วงเวลาเป็น 0 คุณควรเพิ่ม "s" ด้วย
เจดับบลิว

นี่มันเจ๋งมาก. สำหรับ TS ฉันต้องเพิ่มผู้ประกอบการเอกในวันที่let seconds = Math.floor((+new Date() - date) / 1000);
Ben Racicot

ทำไมคุณถึงตรวจสอบแม้กระทั่งinterval === 0ในครั้งสุดท้ายif?
smartmouse

1
@ smartmouse เพื่อที่จะพูดว่า "0 วินาที" แทน "0 วินาที"
rob

14

คุณอาจต้องการดู humanized_time_span: https://github.com/layam/js_humanized_time_span

มันเป็นกรอบที่ไม่เชื่อเรื่องพระเจ้าและปรับแต่งได้อย่างเต็มที่

เพียงดาวน์โหลด / รวมสคริปต์แล้วคุณสามารถทำได้:

humanized_time_span("2011-05-11 12:00:00")  
   => '3 hours ago'

humanized_time_span("2011-05-11 12:00:00", "2011-05-11 16:00:00)  
   => '4 hours ago'

หรือแม้กระทั่งสิ่งนี้:

var custom_date_formats = {
  past: [
    { ceiling: 60, text: "less than a minute ago" },
    { ceiling: 86400, text: "$hours hours, $minutes minutes and $seconds seconds ago" },
    { ceiling: null, text: "$years years ago" }
  ],
  future: [
    { ceiling: 60, text: "in less than a minute" },
    { ceiling: 86400, text: "in $hours hours, $minutes minutes and $seconds seconds time" },
    { ceiling: null, text: "in $years years" }
  ]
}

humanized_time_span("2010/09/10 10:00:00", "2010/09/10 10:00:05", custom_date_formats) 
  => "less than a minute ago"

อ่านเอกสารสำหรับข้อมูลเพิ่มเติม


4
เพียงหมายความว่ามันไม่พึ่งพา jQuery หรือแม้แต่มี DOM
Will Tomlins

มันทำให้ฉันNaN years agoทำไม

ฉันเข้าใจแล้ว ... ตัวอย่างการใช้ของคุณมันผิด คุณกำหนดตัวเลขเป็นตัวแรกด้วยเครื่องหมายทับแทน "-" .. เช่นนี้humanized_time_span("2011/05/11 12:00:00")

มันอาจจะขึ้นอยู่กับวัฒนธรรมท้องถิ่นของคุณและแตกต่างกันระหว่างผู้ใช้ :)
Mikus

13

เปลี่ยนฟังก์ชั่นด้านบนเป็น

function timeSince(date) {

    var seconds = Math.floor(((new Date().getTime()/1000) - date)),
    interval = Math.floor(seconds / 31536000);

    if (interval > 1) return interval + "y";

    interval = Math.floor(seconds / 2592000);
    if (interval > 1) return interval + "m";

    interval = Math.floor(seconds / 86400);
    if (interval >= 1) return interval + "d";

    interval = Math.floor(seconds / 3600);
    if (interval >= 1) return interval + "h";

    interval = Math.floor(seconds / 60);
    if (interval > 1) return interval + "m ";

    return Math.floor(seconds) + "s";
}

มิฉะนั้นจะแสดงสิ่งต่าง ๆ เช่น "75 นาที" (ระหว่าง 1 ถึง 2 ชั่วโมง) นอกจากนี้ยังถือว่าวันที่ป้อนข้อมูลเป็นเวลา Unix


กรุณาแบ่งวันด้วย 1,000 โปรด

ฉันใช้สิ่งนี้ซึ่งข้อมูลมาจากฐานข้อมูลที่มีการประทับเวลา Unix ในไม่กี่วินาที เมื่อหน่วยเป็นมิลลิวินาทีคุณจะต้องหารด้วย 1,000
PanMan

11

รหัสที่สามารถอ่านได้และข้ามเบราว์เซอร์ได้มากมาย:

ตามที่กำหนดโดย @Travis

var DURATION_IN_SECONDS = {
  epochs: ['year', 'month', 'day', 'hour', 'minute'],
  year: 31536000,
  month: 2592000,
  day: 86400,
  hour: 3600,
  minute: 60
};

function getDuration(seconds) {
  var epoch, interval;

  for (var i = 0; i < DURATION_IN_SECONDS.epochs.length; i++) {
    epoch = DURATION_IN_SECONDS.epochs[i];
    interval = Math.floor(seconds / DURATION_IN_SECONDS[epoch]);
    if (interval >= 1) {
      return {
        interval: interval,
        epoch: epoch
      };
    }
  }

};

function timeSince(date) {
  var seconds = Math.floor((new Date() - new Date(date)) / 1000);
  var duration = getDuration(seconds);
  var suffix = (duration.interval > 1 || duration.interval === 0) ? 's' : '';
  return duration.interval + ' ' + duration.epoch + suffix;
};

alert(timeSince('2015-09-17T18:53:23'));


โปรดทราบว่าสิ่งนี้ทำให้สมมติฐานบางอย่างผิดพลาดเช่นทุกวันเป็น 86,400 วินาที (ยกเว้นเขตเวลาถูกตั้งค่าเป็น UTC สิ่งนี้ไม่ได้เกิดขึ้นเสมอขอบคุณ UTC)
ItalyPaleAle

10

รุ่นที่สั้นกว่าที่ใช้โดยLokely :

const intervals = [
  { label: 'year', seconds: 31536000 },
  { label: 'month', seconds: 2592000 },
  { label: 'day', seconds: 86400 },
  { label: 'hour', seconds: 3600 },
  { label: 'minute', seconds: 60 },
  { label: 'second', seconds: 0 }
];

function timeSince(date) {
  const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
  const interval = intervals.find(i => i.seconds < seconds);
  const count = Math.floor(seconds / interval.seconds);
  return `${count} ${interval.label}${count !== 1 ? 's' : ''} ago`;
}

2
ช่วงเวลาที่สั้นที่สุดมีระยะเวลาเป็นศูนย์วินาทีซึ่งจะส่งผลให้เกิดการหารด้วยข้อผิดพลาดเป็นศูนย์
apk

@apk ถูกต้อง <60 วินาทีมันพิมพ์Infinity seconds ago
leonheess

8

ต่อจากนี้ยูนิกซ์ประทับเวลาพารามิเตอร์

function timeSince(ts){
    now = new Date();
    ts = new Date(ts*1000);
    var delta = now.getTime() - ts.getTime();

    delta = delta/1000; //us to s

    var ps, pm, ph, pd, min, hou, sec, days;

    if(delta<=59){
        ps = (delta>1) ? "s": "";
        return delta+" second"+ps
    }

    if(delta>=60 && delta<=3599){
        min = Math.floor(delta/60);
        sec = delta-(min*60);
        pm = (min>1) ? "s": "";
        ps = (sec>1) ? "s": "";
        return min+" minute"+pm+" "+sec+" second"+ps;
    }

    if(delta>=3600 && delta<=86399){
        hou = Math.floor(delta/3600);
        min = Math.floor((delta-(hou*3600))/60);
        ph = (hou>1) ? "s": "";
        pm = (min>1) ? "s": "";
        return hou+" hour"+ph+" "+min+" minute"+pm;
    } 

    if(delta>=86400){
        days = Math.floor(delta/86400);
        hou =  Math.floor((delta-(days*86400))/60/60);
        pd = (days>1) ? "s": "";
        ph = (hou>1) ? "s": "";
        return days+" day"+pd+" "+hou+" hour"+ph;
    }

}

5

รหัส ES6 ที่ให้บริการโดย @ user1012181

// Epochs
const epochs = [
    ['year', 31536000],
    ['month', 2592000],
    ['day', 86400],
    ['hour', 3600],
    ['minute', 60],
    ['second', 1]
];


// Get duration
const getDuration = (timeAgoInSeconds) => {
    for (let [name, seconds] of epochs) {
        const interval = Math.floor(timeAgoInSeconds / seconds);

        if (interval >= 1) {
            return {
                interval: interval,
                epoch: name
            };
        }
    }
};


// Calculate
const timeAgo = (date) => {
    const timeAgoInSeconds = Math.floor((new Date() - new Date(date)) / 1000);
    const {interval, epoch} = getDuration(timeAgoInSeconds);
    const suffix = interval === 1 ? '' : 's';

    return `${interval} ${epoch}${suffix} ago`;
};

แก้ไขด้วยคำแนะนำ @ ibe-vanmeenen (ขอบคุณ!)


คุณควรรวม "วินาที: 1" ไว้ใน EPOCHS ไม่เช่นนั้นจะหยุดถ้าน้อยกว่า 1 นาทีที่แล้ว :) 3 vars สุดท้ายอาจเป็นค่าคงที่ไม่ได้หรือไม่
Ibe Vanmeenen

1
นอกจากนี้ EPOCHS ควรเป็นอาร์เรย์เนื่องจากวัตถุไม่รับประกันการสั่งซื้อคุณสมบัติ ผมเคยเก็บไว้ในการเปลี่ยนแปลงของฉันgist.github.com/IbeVanmeenen/4e3e58820c9168806e57530563612886 คุณสามารถคัดลอกพวกเขาเพื่อแก้ไขคำตอบนี้ :)
Ibe Vanmeenen

5

รุ่นที่ง่ายและอ่านได้:

const NOW = new Date()
const times = [["second", 1], ["minute", 60], ["hour", 3600], ["day", 86400], ["week", 604800], ["month", 2592000], ["year", 31536000]]

function timeAgo(date) {
    var diff = Math.round((NOW - date) / 1000)
    for (var t = 0; t < times.length; t++) {
        if (diff < times[t][1]) {
            if (t == 0) {
                return "Just now"
            } else {
                diff = Math.round(diff / times[t - 1][1])
                return diff + " " + times[t - 1][0] + (diff == 1?" ago":"s ago")
            }
        }
    }
}

3

ฉันเขียนด้วย js และ python ที่ใช้ในโครงการสองโครงการดีมากและเรียบง่าย: ไลบรารีที่เรียบง่าย (น้อยกว่า 2kb) ที่ใช้จัดรูปแบบวันที่ด้วย*** time agoคำสั่ง

เรียบง่ายเล็กใช้งานง่ายและผ่านการทดสอบอย่างดี

  1. npm install timeago.js

  2. import timeago from 'timeago.js'; // or use script tag

  3. การใช้งาน formatAPI

ตัวอย่าง:

var timeagoIns  = timeago();
timeagoIns .format('2016-06-12');

นอกจากนี้คุณสามารถแสดงผลในเวลาจริง

var timeagoIns = timeago();
timeagoIns.render(document.querySelectorAll('time'));

ตั้งแต่ 4.0 คุณสามารถใช้การนำเข้าที่ถูกทำลายได้แทน:import { format, render, cancel, register } from 'timeago.js';
cmfolio

3

แม้ว่าคำถามจะถูกถามมานานแล้ว แต่การเขียนคำตอบนี้ด้วยความหวังว่าจะช่วยใครซักคน

ผ่านวันที่ที่คุณต้องการเริ่มนับ การใช้moment().fromNow()ของmomentjs : (โปรดดูข้อมูลเพิ่มเติมที่นี่ )

getRelativeTime(date) {
    const d = new Date(date * 1000);
    return moment(d).fromNow();
}

หากคุณต้องการเปลี่ยนข้อมูลที่ให้ไว้สำหรับวันที่จากตอนนี้คุณเขียนเวลาที่กำหนดเองของคุณสักครู่

ตัวอย่างเช่นในกรณีของฉันเองฉันต้องการที่จะพิมพ์'one month ago'แทน'a month ago'( ให้บริการโดยช่วงเวลา (d) .fromNow () ) ในกรณีนี้คุณสามารถเขียนสิ่งที่ระบุด้านล่าง

moment.updateLocale('en', {
    relativeTime: {
        future: 'in %s',
        past: '%s ago',
        s: 'a few seconds',
        ss: '%d seconds',
        m: '1 m',
        mm: '%d minutes',
        h: '1 h',
        hh: '%d hours',
        d: '1 d',
        dd: '%d days',
        M: '1 month',
        MM: '%d months',
        y: '1 y',
        yy: '%d years'
    }
});

หมายเหตุ : ฉันเขียนโค้ดสำหรับโครงการในAgular 6


3

ยังสามารถใช้ปลั๊กอินdayjs relativeTimeเพื่อแก้ไขปัญหานี้ได้

import * as dayjs from 'dayjs';
import * as relativeTime from 'dayjs/plugin/relativeTime';

dayjs.extend(relativeTime);
dayjs(dayjs('1990')).fromNow(); // x years ago

3

สิ่งนี้ควรจัดการกับการประทับเวลาที่ถูกต้องใด ๆ รวมถึง Date.now (), หน่วยเอกพจน์และวันที่ในอนาคต ฉันออกไปหลายเดือน แต่สิ่งเหล่านี้ควรเพิ่มได้ง่ายฉันพยายามทำให้มันอ่านง่ายที่สุดเท่าที่จะทำได้

function getTimeInterval(date) {
  let seconds = Math.floor((Date.now() - date) / 1000);
  let unit = "second";
  let direction = "ago";
  if (seconds < 0) {
    seconds = -seconds;
    direction = "from now";
  }
  let value = seconds;
  if (seconds >= 31536000) {
    value = Math.floor(seconds / 31536000);
    unit = "year";
  } else if (seconds >= 86400) {
    value = Math.floor(seconds / 86400);
    unit = "day";
  } else if (seconds >= 3600) {
    value = Math.floor(seconds / 3600);
    unit = "hour";
  } else if (seconds >= 60) {
    value = Math.floor(seconds / 60);
    unit = "minute";
  }
  if (value != 1)
    unit = unit + "s";
  return value + " " + unit + " " + direction;
}

console.log(getTimeInterval(Date.now())); // 0 seconds ago
console.log(getTimeInterval(Date.now() + 1000)); // 1 second from now
console.log(getTimeInterval(Date.now() - 1000)); // 1 second ago
console.log(getTimeInterval(Date.now() + 60000)); // 1 minute from now
console.log(getTimeInterval(Date.now() - 120000)); // 2 minutes ago
console.log(getTimeInterval(Date.now() + 120000)); // 2 minutes from now
console.log(getTimeInterval(Date.now() + 3600000)); // 1 hour from now
console.log(getTimeInterval(Date.now() + 360000000000)); // 11 years from now
console.log(getTimeInterval(0)); // 49 years ago


2

ฉันได้แก้ไขเวอร์ชันของ Sky Sanders การดำเนินการ Math.floor (... ) ได้รับการประเมินในบล็อก if

       var timeSince = function(date) {
            var seconds = Math.floor((new Date() - date) / 1000);
            var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
            if (seconds < 5){
                return "just now";
            }else if (seconds < 60){
                return seconds + " seconds ago";
            }
            else if (seconds < 3600) {
                minutes = Math.floor(seconds/60)
                if(minutes > 1)
                    return minutes + " minutes ago";
                else
                    return "1 minute ago";
            }
            else if (seconds < 86400) {
                hours = Math.floor(seconds/3600)
                if(hours > 1)
                    return hours + " hours ago";
                else
                    return "1 hour ago";
            }
            //2 days and no more
            else if (seconds < 172800) {
                days = Math.floor(seconds/86400)
                if(days > 1)
                    return days + " days ago";
                else
                    return "1 day ago";
            }
            else{

                //return new Date(time).toLocaleDateString();
                return date.getDate().toString() + " " + months[date.getMonth()] + ", " + date.getFullYear();
            }
        }

มีการพิมพ์ผิดในช่วงสุดท้ายถ้าreturn days + "1 day ago";ควรจะเป็นreturn "1 day ago";
Marco Gurnari

2
function dateToHowManyAgo(stringDate){
    var currDate = new Date();
    var diffMs=currDate.getTime() - new Date(stringDate).getTime();
    var sec=diffMs/1000;
    if(sec<60)
        return parseInt(sec)+' second'+(parseInt(sec)>1?'s':'')+' ago';
    var min=sec/60;
    if(min<60)
        return parseInt(min)+' minute'+(parseInt(min)>1?'s':'')+' ago';
    var h=min/60;
    if(h<24)
        return parseInt(h)+' hour'+(parseInt(h)>1?'s':'')+' ago';
    var d=h/24;
    if(d<30)
        return parseInt(d)+' day'+(parseInt(d)>1?'s':'')+' ago';
    var m=d/30;
    if(m<12)
        return parseInt(m)+' month'+(parseInt(m)>1?'s':'')+' ago';
    var y=m/12;
    return parseInt(y)+' year'+(parseInt(y)>1?'s':'')+' ago';
}
console.log(dateToHowManyAgo('2019-11-07 19:17:06'));

1
function timeago(date) {
    var seconds = Math.floor((new Date() - date) / 1000);
    if(Math.round(seconds/(60*60*24*365.25)) >= 2) return Math.round(seconds/(60*60*24*365.25)) + " years ago";
    else if(Math.round(seconds/(60*60*24*365.25)) >= 1) return "1 year ago";
    else if(Math.round(seconds/(60*60*24*30.4)) >= 2) return Math.round(seconds/(60*60*24*30.4)) + " months ago";
    else if(Math.round(seconds/(60*60*24*30.4)) >= 1) return "1 month ago";
    else if(Math.round(seconds/(60*60*24*7)) >= 2) return Math.round(seconds/(60*60*24*7)) + " weeks ago";
    else if(Math.round(seconds/(60*60*24*7)) >= 1) return "1 week ago";
    else if(Math.round(seconds/(60*60*24)) >= 2) return Math.round(seconds/(60*60*24)) + " days ago";
    else if(Math.round(seconds/(60*60*24)) >= 1) return "1 day ago";
    else if(Math.round(seconds/(60*60)) >= 2) return Math.round(seconds/(60*60)) + " hours ago";
    else if(Math.round(seconds/(60*60)) >= 1) return "1 hour ago";
    else if(Math.round(seconds/60) >= 2) return Math.round(seconds/60) + " minutes ago";
    else if(Math.round(seconds/60) >= 1) return "1 minute ago";
    else if(seconds >= 2)return seconds + " seconds ago";
    else return seconds + "1 second ago";
}

1

ทางออกของฉัน ..

(function(global){
            const SECOND   = 1;
            const MINUTE   = 60;
            const HOUR     = 3600;
            const DAY      = 86400;
            const MONTH    = 2629746;
            const YEAR     = 31556952;
            const DECADE   = 315569520;

            global.timeAgo = function(date){
                var now = new Date();
                var diff = Math.round(( now - date ) / 1000);

                var unit = '';
                var num = 0;
                var plural = false;

                switch(true){
                    case diff <= 0:
                        return 'just now';
                    break;

                    case diff < MINUTE:
                        num = Math.round(diff / SECOND);
                        unit = 'sec';
                        plural = num > 1;
                    break;

                    case diff < HOUR:
                        num = Math.round(diff / MINUTE);
                        unit = 'min';
                        plural = num > 1;
                    break;

                    case diff < DAY:
                        num = Math.round(diff / HOUR);
                        unit = 'hour';
                        plural = num > 1;
                    break;

                    case diff < MONTH:
                        num = Math.round(diff / DAY);
                        unit = 'day';
                        plural = num > 1;
                    break;

                    case diff < YEAR:
                        num = Math.round(diff / MONTH);
                        unit = 'month';
                        plural = num > 1;
                    break;

                    case diff < DECADE:
                        num = Math.round(diff / YEAR);
                        unit = 'year';
                        plural = num > 1;
                    break;

                    default:
                        num = Math.round(diff / YEAR);
                        unit = 'year';
                        plural = num > 1;
                }

                var str = '';
                if(num){
                    str += `${num} `;
                }

                str += `${unit}`;

                if(plural){
                    str += 's';
                }

                str += ' ago';

                return str;
            }
        })(window);

        console.log(timeAgo(new Date()));
        console.log(timeAgo(new Date('Jun 03 2018 15:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('Jun 03 2018 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('May 28 2018 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('May 28 2017 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('May 28 2000 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('Sep 10 1994 13:12:19 GMT+0300 (FLE Daylight Time)')));

1

ฉันแทงที่นี้ตามคำตอบอื่น ๆ

function timeSince(date) {
    let minute = 60;
    let hour   = minute * 60;
    let day    = hour   * 24;
    let month  = day    * 30;
    let year   = day    * 365;

    let suffix = ' ago';

    let elapsed = Math.floor((Date.now() - date) / 1000);

    if (elapsed < minute) {
        return 'just now';
    }

    // get an array in the form of [number, string]
    let a = elapsed < hour  && [Math.floor(elapsed / minute), 'minute'] ||
            elapsed < day   && [Math.floor(elapsed / hour), 'hour']     ||
            elapsed < month && [Math.floor(elapsed / day), 'day']       ||
            elapsed < year  && [Math.floor(elapsed / month), 'month']   ||
            [Math.floor(elapsed / year), 'year'];

    // pluralise and append suffix
    return a[0] + ' ' + a[1] + (a[0] === 1 ? '' : 's') + suffix;
}

0

ฉันกำลังมองหาคำตอบสำหรับเรื่องนี้และเกือบจะใช้หนึ่งในวิธีแก้ปัญหาเหล่านี้ แต่เพื่อนร่วมงานเตือนให้ฉันตรวจสอบ react-intlห้องสมุดเนื่องจากเราใช้มันอยู่แล้ว

ดังนั้นการเพิ่มโซลูชั่น ... ในกรณีที่คุณใช้react-intlห้องสมุดพวกเขามี<FormattedRelative>ส่วนประกอบสำหรับสิ่งนี้

https://github.com/yahoo/react-intl/wiki/Components#formattedrelative


0

นี่คือสิ่งที่ฉันทำ (วัตถุคืนค่าหน่วยเวลาตามด้วยค่า):

function timeSince(post_date, reference)
{
	var reference = reference ? new Date(reference) : new Date(),
		diff = reference - new Date(post_date + ' GMT-0000'),
		date = new Date(diff),
		object = { unit: null, value: null };
	
	if (diff < 86400000)
	{
		var secs  = date.getSeconds(),
			mins  = date.getMinutes(),
			hours = date.getHours(),
			array = [ ['second', secs], ['minute', mins], ['hour', hours] ];
	}
	else
	{
		var days   = date.getDate(),
			weeks  = Math.floor(days / 7),
			months = date.getMonth(),
			years  = date.getFullYear() - 1970,
			array  = [ ['day', days], ['week', weeks], ['month', months], ['year', years] ];
	}

	for (var i = 0; i < array.length; i++)
	{
		array[i][0] += array[i][1] != 1 ? 's' : '';

		object.unit  = array[i][1] >= 1 ? array[i][0] : object.unit;
		object.value = array[i][1] >= 1 ? array[i][1] : object.value;
	}

	return object;
}

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