web-dev-qa-db-fra.com

Comment arrondir l'heure au quart d'heure près en JavaScript?

Par exemple:

Given time: 08:22 => Rounded to: 08:15

Given time: 08:23 => Rounded to: 08:30

Devrait être assez simple. Mais tout ce que j'ai pu produire est long, pas très bon code pour résoudre le problème. Mon esprit est juste devenu vide.

Cordialement

42
pantarhei

Étant donné que vous avez des heures et des minutes dans les variables (sinon, vous pouvez les obtenir à partir de l'instance Date en utilisant Date instance functions ):

var m = (parseInt((minutes + 7.5)/15) * 15) % 60;
var h = minutes > 52 ? (hours === 23 ? 0 : ++hours) : hours;

les minutes peuvent également être calculées en utilisant Math.round():

var m = (Math.round(minutes/15) * 15) % 60;

ou le faire dans une expression plus javascript-sophistiquée sans aucune fonction:

var m = (((minutes + 7.5)/15 | 0) * 15) % 60;
var h = ((((minutes/105) + .5) | 0) + hours) % 24;

Vous pouvez vérifier que le test jsPerf montre que Math.round() est le plus lent des trois alors que le dernier est le plus rapide, car il s’agit simplement d’une expression sans appel de fonction (aucune surcharge d’appel de fonction (manipulation de la pile, bien que les fonctions natives puissent être traitées différemment en Javascript VM) . // ---- 

82
Robert Koritnik

Cette fonction arrondit l'heure au quart d'heure près.

function roundTimeQuarterHour(time) {
    var timeToReturn = new Date(time);

    timeToReturn.setMilliseconds(Math.round(time.getMilliseconds() / 1000) * 1000);
    timeToReturn.setSeconds(Math.round(timeToReturn.getSeconds() / 60) * 60);
    timeToReturn.setMinutes(Math.round(timeToReturn.getMinutes() / 15) * 15);
    return timeToReturn;
}
10
Antoine Desbois

Le code ici est un peu prolixe mais je suis sûr que vous verrez comment vous pouvez combiner les lignes pour rendre cela plus court Je l'ai laissé de cette façon pour montrer clairement les étapes:

var now = new Date();
var mins = now.getMinutes();
var quarterHours = Math.round(mins/15);
if (quarterHours == 4)
{
    now.setHours(now.getHours()+1);
}
var rounded = (quarterHours*15)%60;
now.setMinutes(rounded);
document.write(now);
6
Lazarus

Avec chaîne de temps

Voici une méthode qui arrondira une chaîne temporelle semblable à celle que vous avez présentée. Par exemple "08:22"

let roundTime = (time, minutesToRound) => {

    let [hours, minutes] = time.split(':');
    hours = parseInt(hours);
    minutes = parseInt(minutes);

    // Convert hours and minutes to time in minutes
    time = (hours * 60) + minutes; 

    let rounded = Math.round(time / minutesToRound) * minutesToRound;
    let rHr = ''+Math.floor(rounded / 60)
    let rMin = ''+ rounded % 60

    return rHr.padStart(2, '0')+':'+rMin.padStart(2, '0')
}

// USAGE //

// Round time to 15 minutes
roundTime('8:07', 15); // "08:00"
roundTime('7:53', 15); // "08:00"
roundTime('7:52', 15); // "07:45"

Avec des heures et des minutes déjà fractionnées

Vous pouvez utiliser cette méthode si vous n'avez pas besoin d'analyser les chaînes d'heure et de minute comme le montre votre exemple.

let roundTime = (hours, minutes, minutesToRound) => {

    // Convert hours and minutes to minutes
    time = (hours * 60) + minutes; 
    let rounded = Math.round(time / minutesToRound) * minutesToRound;

    let roundedHours = Math.floor(rounded / 60)
    let roundedMinutes = rounded % 60

    return { hours: roundedHours, minutes: roundedMinutes }
}

// USAGE //

// Round time to 15 minutes
roundTime(7, 52, 15); // {hours: 7, minutes: 45}
roundTime(7, 53, 15); // {hours: 8, minutes: 0}
roundTime(1, 10, 15); // {hours: 1, minutes: 15}

Avec un objet Date existant

Ou, si vous souhaitez arrondir un objet de date déjà existant aux x minutes les plus proches, vous pouvez utiliser cette méthode.

Si vous ne lui donnez pas de date, il arrondira l'heure actuelle. Dans votre cas, vous pouvez arrondir aux 15 minutes les plus proches.

let getRoundedDate = (minutes, d=new Date()) => {

  let ms = 1000 * 60 * minutes; // convert minutes to ms
  let roundedDate = new Date(Math.round(d.getTime() / ms) * ms);

  return roundedDate
}


// USAGE //

// Round existing date to 5 minutes
getRoundedDate(15, new Date()); // 2018-01-26T00:45:00.000Z

// Get current time rounded to 30 minutes
getRoundedDate(30); // 2018-01-26T00:30:00.000Z
5
joshuakcockrell

Il existe un package NPM@qc/date-round qui peut être utilisé. Étant donné que vous avez une instance Date à arrondir

import { round } from '@qc/date-round'

const dateIn = ...; // The date to be rounded
const interval = 15 * 60 * 1000; // 15 minutes (aka quarter hour)
const dateOut = round(dateIn, interval)

Ensuite, vous pouvez utiliser date-fns pour formater la date

import format from 'date-fns/format';

console.log(format(dateOut, 'HH:mm')) // 24-hr
console.log(format(dateOut, 'hh:mm a')) // 12-hr
0
Danny Hurlburt