La question est de savoir comment formater JavaScript Date
sous la forme d'une chaîne indiquant le temps écoulé, similaire à la façon dont vous voyez les temps affichés sur Stack Overflow.
par exemple.
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)));
Peut-être un excès dans ce cas, mais si l'occasion se présente, moment.js _ est tout simplement génial!
Moment.js est une bibliothèque javascript datetime, pour l'utiliser dans un tel scénario, vous feriez:
moment(yourdate).fromNow()
_ { http://momentjs.com/docs/#/displaying/fromnow/
2018 addenda: Luxon est une nouvelle bibliothèque moderne qui vaut peut-être le détour!
Je n'ai pas vérifié (bien que cela ne serait pas difficile), mais je pense que les sites Stack Exchange utilisent le plugin jquery.timeago
pour créer ces chaînes temporelles.
Il est assez facile d'utiliser le plugin, il est propre et se met à jour automatiquement.
Voici un exemple rapide (de la page d'accueil du plugin):
Commencez par charger jQuery et le plugin:
<script src="jquery.min.js" type="text/javascript"></script> <script src="jquery.timeago.js" type="text/javascript"></script>
Maintenant, attachons-le à votre timestamps sur DOM ready:
jQuery(document).ready(function() {
jQuery("abbr.timeago").timeago(); });Cela transformera tous les
abbr
éléments avec une classe detimeago
et un ISO 8601 timestamp dans le titre:<abbr class="timeago" title="2008-07-17T09:24:17Z">July 17, 2008</abbr>
dans quelque chose comme ceci:<abbr class="timeago" title="July 17, 2008">about a year ago</abbr>
qui rendements: il y a environ un an. Comme le temps passe, les horodatages seront mettre à jour automatiquement.
Cela vous montrera les formats d'heure passés et précédents tels que 'il y a 2 jours' '' 10 minutes à partir de maintenant 'et vous pouvez le transmettre soit un objet Date, un horodatage numérique ou une chaîne de date
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)));
Voici une légère modification de la solution de Sky Sander qui permet de saisir la date sous forme de chaîne et est capable d'afficher des plages telles que "1 minute" au lieu de "73 secondes"
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)));
Vous voudrez peut-être regarder humanized_time_span: https://github.com/layam/js_humanized_time_span
Il est agnostique et entièrement personnalisable.
Il suffit de télécharger/inclure le script et ensuite vous pouvez le faire:
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'
ou même ceci:
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"
Lisez la documentation pour plus d'informations.
Modification de la fonction ci-dessus en
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";
}
Sinon, cela afficherait des choses comme "75 minutes" (entre 1 et 2 heures). Il suppose également que la date d'entrée est un horodatage Unix.
Code lisible et compatible avec tous les navigateurs:
Comme donné par @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'));
à partir de maintenant, unix timestamp param,
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;
}
}
Une version plus courte utilisée par 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`;
}
Une version ES6 du code fourni par @ 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`;
};
Édité avec les suggestions de @ ibe-vanmeenen. (Merci !)
J'écris un avec js et python, utilisé dans deux projets, très agréable et simple: une bibliothèque simple (moins de 2 Ko) utilisée pour formater la date avec l'instruction *** time ago
.
simple, petit, facile à utiliser et bien testé.
npm install timeago.js
import timeago from 'timeago.js'; // or use script tag
utilisez api format
.
Échantillon:
var timeagoIns = timeago();
timeagoIns .format('2016-06-12');
Aussi, vous pouvez effectuer un rendu en temps réel.
var timeagoIns = timeago();
timeagoIns.render(document.querySelectorAll('time'));
J'ai modifié la version de Sky Sanders. Les opérations Math.floor (...) sont évaluées dans le bloc 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();
}
}
Version simple et lisible:
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")
}
}
}
}
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";
}
Ma solution ..
(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)')));
Bien que la question ait été posée il y a assez longtemps, écrire cette réponse dans l'espoir que cela aidera quelqu'un.
Passez la date à partir de laquelle vous voulez commencer à compter. Utilisation de moment().fromNow()
of momentjs: (Voir plus d'informations ici )
getRelativeTime(date) {
const d = new Date(date * 1000);
return moment(d).fromNow();
}
Si vous souhaitez modifier les informations fournies pour les dates de Maintenant, écrivez votre heure relative personnalisée pour le moment.
Par exemple, dans mon cas, je voulais imprimer 'one month ago'
au lieu de 'a month ago'
(fourni par moment (d) .fromNow ()). Dans ce cas, vous pouvez écrire quelque chose donné ci-dessous.
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'
}
});
NOTE: j'ai écrit mon code de projet dans Agular 6
Voici ce que j'ai fait (l'objet renvoie l'unité de temps avec sa valeur):
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;
}
Je cherchais une réponse à cette question et j'ai presque mis en œuvre l'une de ces solutions, mais un collègue m'a rappelé de vérifier la bibliothèque react-intl
puisque nous l'utilisions déjà.
Donc, en ajoutant aux solutions ... dans le cas où vous utilisez la bibliothèque react-intl
, ils ont un composant <FormattedRelative>
pour cela.
https://github.com/yahoo/react-intl/wiki/Components#formattedrelative
Peut également utiliser le plugin dayjs relativeTime pour résoudre ce problème.
import * as dayjs from 'dayjs';
import * as relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);
dayjs(dayjs('1990')).fromNow(); // x years ago