Moment: Redondeo al intervalo de 15 minutos más cercano.

Creado en 27 jul. 2013  ·  18Comentarios  ·  Fuente: moment/moment

Me preguntaba si hay una manera de redondear hacia arriba o hacia abajo al intervalo de 15 minutos más cercano. Creo que esta sería una gran característica para tener en este momento, ya que algunas bibliotecas como datejs tienen esta funcionalidad de lo que vi al buscar. Mi escenario es que tengo puntos de datos que están segmentados en cubos de 15 minutos. La herramienta de selección devuelve cualquier bloque de tiempo y necesito redondear hacia abajo a los 15 minutos más cercanos y redondear hacia arriba para el tiempo de finalización.

Hacerlo de esta manera (http://stackoverflow.com/questions/4968250/how-to-round-time-to-the-nearest-quarter-hour-in-javascript) parece que sería un fastidio ... cuando Sería útil tenerlo en la propia lib.

todo

Comentario más útil

No hay necesidad de complicar, matemáticas 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)

Salidas al cuarto de 15 minutos más cercano.

Todos 18 comentarios

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

Creé esto para mi propio uso y pensé que podría ayudar a otros. Tenga en cuenta que se redondea a los SIGUIENTES 15 min más cercanos.

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

EDITAR: eliminado this.incrementHours () a favor de this.add ('horas', 1);

¿Puede agregar estas funciones al momento? Sería realmente bueno poder redondear a los intervalos de tiempo más cercanos, siguientes y anteriores ... Hay millones de resultados de Google para esto y cientos de upvotes de desbordamiento de pila ...

Ahora que lo miro de nuevo, no tengo idea de cómo estaba funcionando incrementHours.
Edité mi publicación sobre el problema con el código corregido. ¡Disfrutar!

El lunes 10 de marzo de 2014 a las 2:29 p.m., Blake Niemyjski
[email protected]ó :

¿Cuál fue su función para incrementHours? Supongo que eso también hizo días
también.

Responda a este correo electrónico directamente o véalo en Gi
.

gracias por ese método @zbarnett . Exactamente lo que necesitaba para mi proyecto.

Bueno, podemos usar la interfaz startOf como esta startOf(15, 'm') . Puede funcionar para todas las unidades. Esperando RP :)

Aquí hay una fórmula bastante simple (en la sintaxis de Coffeescript, ya que ese es el contexto en el que me encontré con este problema):

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

Estoy lo suficientemente ocupado con otras cosas en este momento, pero si alguien quiere tomar este código y ponerlo directamente en un PR, no dude.

Cierre a favor de # 1595

No hay necesidad de complicar, matemáticas 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)

Salidas al cuarto de 15 minutos más cercano.

No pude hacer que la solución de @janwerkhoven funcionara, así que aquí está la mía:

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

@ tierra5hark

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

Probado en Code Pen

La parte crucial es hacer .clone() . Sin él, estaría editando el moment() que es un error común cuando se usa Moment.js.

Prueba esto chicos

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"))

Tarde para la fiesta, lo sé, pero ...

La función nearestMinutes @janwerkhoven no es correcta; eso implica que se redondeará hacia arriba o hacia abajo según el minuto, por lo que al redondear a los 15 más cercanos esperaríamos 12:34 -> 12:30 y 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 solución de @Silviusconcept supera esto con minutesRounded

@kevlarr
Math.round(39/15) devuelve 3 y no 2.
Math.round(39/15) * 15 devuelve 45 no 30.

Jaja, eso es lo que me pasa por leer demasiados hilos al final del día cuando no he dormido. Estaba haciendo Math.floor

¡Me gusta _zbarnett solution_ ! Fácil de usar
Pequeña actualización de la función _ this.milliseconds (0); _

var newdate = turno.date.clone (). roundNext15Min (). add (anticipación, 'minutos');

moment.fn.roundNext15Min = function () {
intervalos var = Math.floor (this.minutes () / 15);
si (esto.minutos ()% 15! = 0)
intervalos ++;
si (intervalos == 4) {
this.add ('horas', 1);
intervalos = 0;
}
this.minutes (intervalos * 15);
this.seconds (0);
_ this.milliseconds (0); _
devuelve esto;
}

Mi versión de una respuesta

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

Úselo así:

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

Estas funciones cambiarán el objeto original, use clone() cuando sea necesario

otra solución sería:
let next15Minutes = moment().add(15, 'minutes'); next15Minutes.minutes(Math.floor(next15Minutes.minutes() / 15) * 15); next15Minutes.format('HH:mm');

¿Fue útil esta página
0 / 5 - 0 calificaciones