Moment: Arrondi à l'intervalle de 15 minutes le plus proche.

Créé le 27 juil. 2013  ·  18Commentaires  ·  Source: moment/moment

Je me demandais s'il y avait un moyen pour moi d'arrondir vers le haut ou vers le bas à l'intervalle de 15 minutes le plus proche. Je pense que ce serait une excellente fonctionnalité à avoir en ce moment car certaines bibliothèques comme datejs ont en quelque sorte cette fonctionnalité de ce que j'ai vu lors de la recherche. Mon scénario est que j'ai des points de données qui sont segmentés en seaux de 15 minutes, l'outil de sélection renvoie n'importe quel bloc de temps et je dois arrondir aux 15 minutes les plus proches et arrondir à l'heure de fin.

Faire de cette façon (http://stackoverflow.com/questions/4968250/how-to-round-time-to-the-nearest-quart-hour-in-javascript) semble être pénible .. quand il serait utile d'avoir dans la bibliothèque elle-même.

todo

Commentaire le plus utile

Pas besoin de compliquer, des maths simples :

const rounded = Math.round(moment().minute() / 15) * 15;
const roundedDown = Math.floor(moment().minute() / 15) * 15;
const roundedUp = Math.ceil(moment().minute() / 15) * 15;

moment().minute(roundedUp).second(0)

Sorties au quart de minute le plus proche.

Tous les 18 commentaires

moment.fn.roundMinutes = function () { return ~(this.minutes() / 15) * 15; }

J'ai créé ceci pour mon propre usage et j'ai pensé que cela pourrait aider d'autres. Gardez à l'esprit qu'il arrondit aux 15 minutes SUIVANTES les plus proches.

moment.fn.roundNext15Min = function () {
var intervals = Math.floor(this.minutes() / 15);
if(this.minutes() % 15 != 0)
    intervals++;
    if(intervals == 4) {
        this.add('hours', 1);
        intervals = 0;
    }
    this.minutes(intervals * 15);
    this.seconds(0);
    return this;
}

EDIT : supprimé this.incrementHours() en faveur de this.add('hours', 1);

Pouvez-vous s'il vous plaît ajouter ces fonctions à l'instant .. Ce serait vraiment bien de pouvoir arrondir aux intervalles de temps les plus proches, suivants et précédents... Il y a des millions de résultats google pour cela et des centaines de votes positifs de débordement de pile ..

Maintenant que je le regarde à nouveau, je n'ai aucune idée du fonctionnement de incrementHours.
J'ai édité mon message sur le problème avec le code corrigé. Prendre plaisir!

Le lun. 10 mars 2014 à 14:29, Blake Niemyjski
[email protected] a écrit :

Quelle était votre fonction pour incrementHours ? Je suppose que ça a aussi fait des jours
trop.

Répondez directement à cet e-mail ou consultez-le sur Gi tHubhttps: //github.com/moment/moment/issues/959#issuecomment-37223821
.

merci pour cette méthode @zbarnett . Exactement ce dont j'avais besoin pour mon projet

Eh bien, nous pouvons utiliser l'interface startOf comme ceci startOf(15, 'm') . Cela peut fonctionner pour toutes les unités. En attente des PR :)

Voici une formule assez simple (en syntaxe Coffeescript, puisque c'est le contexte dans lequel j'ai rencontré ce problème):

round_interval = 15
remainder = time.minute() % round_interval
time.subtract('minutes', remainder).add('minutes', if remainder > round_interval / 2 then round_interval else 0)

Je suis assez occupé avec d'autres choses en ce moment, mais si quelqu'un veut prendre ce code et le mettre directement dans un PR, n'hésitez pas.

Clôture en faveur du #1595

Pas besoin de compliquer, des maths simples :

const rounded = Math.round(moment().minute() / 15) * 15;
const roundedDown = Math.floor(moment().minute() / 15) * 15;
const roundedUp = Math.ceil(moment().minute() / 15) * 15;

moment().minute(roundedUp).second(0)

Sorties au quart de minute le plus proche.

Je n'ai pas réussi à faire fonctionner la solution de

function round15(minute) {
  let intervals = [15, 30, 45, 59, 0];
  let closest;
  let min = 90;

  for (let i = 0; i < intervals.length; i++) {
    let iv = intervals[i];
    let maybeMin = Math.abs(minute - iv);

    if (maybeMin < min) {
      min = maybeMin;
      closest = iv;
    }
  }

  if (closest === 59) {
    closest = 0;
  }

  return closest;
}

let myMoment = moment();
myMoment.minutes(round15(myMoment.minutes()));

@ground5hark

function nearestMinutes(interval, someMoment){
  const roundedMinutes = Math.round(someMoment.clone().minute() / interval) * interval;
  return someMoment.clone().minute(roundedMinutes).second(0);
}

function nearestPastMinutes(interval, someMoment){
  const roundedMinutes = Math.floor(someMoment.minute() / interval) * interval;
  return someMoment.clone().minute(roundedMinutes).second(0);
}

function nearestFutureMinutes(interval, someMoment){
  const roundedMinutes = Math.ceil(someMoment.minute() / interval) * interval;
  return someMoment.clone().minute(roundedMinutes).second(0);
}

const now = moment();
const nearest5min = nearestMinutes(5, now);
const nearest15min = nearestMinutes(15, now);
const nearest30min = nearestMinutes(30, now);
const nearestFuture5min = nearestFutureMinutes(5, now);
const nearestPast5min = nearestPastMinutes(5, now);

Testé sur Code Pen

Le point crucial est de faire .clone() . Sans cela, vous modifieriez le moment() ce qui est un piège courant lors de l'utilisation de Moment.js.

Essayez ça les gars

time = moment("01:46", "HH:mm");
round_interval = 30;//15;
intervals = Math.floor(time.minutes() / round_interval);
minutesToRound = time.minutes() % round_interval;
minutesRounded = minutesToRound>round_interval/2 ? round_interval: 0;
minutes = intervals * round_interval + minutesRounded;
time.minutes(minutes);

alert(time.format("HH:mm"))

En retard à la fête, je sais, mais...

La fonction nearestMinutes @janwerkhoven n'est pas correcte ; cela implique qu'il arrondira vers le haut OU vers le bas en fonction de la minute, donc en arrondissant au 15 le plus proche, nous nous attendrions à 12:34 -> 12:30 et 12:39 -> 12:45

const roundedMinutes = Math.round(someMoment.clone().minute() / interval) * interval;

// 12:34 is fine...
// => Math.round(34 / 15) * 15
// => 2 * 15
30

// ... but 12:39 is not - it should be 45
// => Math.round(39 / 15) * 15
// => 2 * 15
30

La solution de @Silviusconcept surmonte cela avec minutesRounded

@kevlarr
Math.round(39/15) renvoie 3 pas 2.
Math.round(39/15) * 15 renvoie 45 et non 30.

Haha c'est ce que je reçois pour lire trop de fils à la fin de la journée quand je n'ai pas dormi.. Je faisais Math.floor

J'aime _zbarnett solution_ ! Facile à utiliser
Petite mise à jour de la fonction _ this.milliseconds(0); _

var newdate=turno.date.clone().roundNext15Min().add(anticipation, 'minutes');

moment.fn.roundNext15Min = fonction () {
var intervalles = Math.floor(this.minutes() / 15);
if(this.minutes() % 15 != 0)
intervalles++;
if(intervalles == 4) {
this.add('heures', 1);
intervalles = 0 ;
}
this.minutes(intervalles * 15);
this.seconds(0);
_ this.milliseconds(0) ; _
retournez ceci;
}

Ma version d'une réponse

const startOf = (m, n, unit) => {
  const units = [
    'year',
    'month',
    'hour',
    'minute',
    'second',
    'millisecond',
  ];
  const pos = units.indexOf(unit);
  if (pos === -1) {
    throw new Error('Unsupported unit');
  }
  for (let i = pos + 1; i < units.length; i++) {
    m.set(units[i], 0);
  }
  m.set(unit, Math.floor(m.get(unit) / n) * n);

  return m;
};

const endOf = (m, n, unit) => {
  const units = [
    'year',
    'month',
    'hour',
    'minute',
    'second',
    'millisecond',
  ];
  const pos = units.indexOf(unit);
  if (pos === -1) {
    throw new Error('Unsupported unit');
  }
  for (let i = pos + 1; i < units.length; i++) {
    m.set(units[i], units[i] === 'millisecond' ? 999 : 59);
  }
  m.set(unit, Math.floor(m.get(unit) / n) * n + n - 1);

  return m;
};

Utilisez comme ceci :

startOf(moment(), 15, 'minute');
endOf(moment(), 15, 'minute')
// with moment-timezone
startOf(moment().tz("Europe/London"), 15, 'minute');

Ces fonctions changeront l'objet d'origine, utilisez clone() si nécessaire

une autre solution serait :
let next15Minutes = moment().add(15, 'minutes'); next15Minutes.minutes(Math.floor(next15Minutes.minutes() / 15) * 15); next15Minutes.format('HH:mm');

Cette page vous a été utile?
0 / 5 - 0 notes