61 votes

Comment arrondir le temps au quart d'heure le plus proche en java ?

Étant donné l'heure d'aujourd'hui, par exemple 14 h 24, comment faire pour qu'elle soit arrondie à 14 h 30 ?

De la même manière, si l'heure est 14h17, comment puis-je l'arrondir à 14h15 ?

96voto

Sean Patrick Floyd Points 109428

Arrondir

Vous devrez utiliser le modulo pour tronquer le quart d'heure :

Date whateverDateYouWant = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(whateverDateYouWant);

int unroundedMinutes = calendar.get(Calendar.MINUTE);
int mod = unroundedMinutes % 15;
calendar.add(Calendar.MINUTE, mod < 8 ? -mod : (15-mod));

Comme l'a fait remarquer EJP, ceci est également OK (remplacement de la dernière ligne, uniquement valable si le calendrier est indulgent ) :

calendar.set(Calendar.MINUTE, unroundedMinutes + mod);

Améliorations

Si vous voulez être exact, vous devrez également tronquer les champs les plus petits :

calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);

Vous pouvez également utiliser DateUtils.truncate() de Apache Commons / Lang pour le faire :

calendar = DateUtils.truncate(calendar, Calendar.MINUTE);

0 votes

Euh, je viens de le construire à partir de la classe de calendrier

2 votes

Cette méthode va arrondir les minutes au quart le plus proche et vous devez ajouter une vérification si elle a été arrondie à l'heure suivante de sorte que vous devez également mettre à jour l'heure...

1 votes

La version actuelle corrige ces problèmes

10voto

Peter Tillemans Points 20129

Avec la réponse ci-dessus, on se retrouve avec toutes sortes de codes intéressants pour gérer les dépassements en heures, jours, etc.

J'utiliserais le temps en ms depuis l'époque.

ajouter 7,5 minutes ou 7,5x60x1000 = 450000

et tronquer à un multiple de 900000

new Date(900000 * ((date.getTime() + 450000) / 900000))

Cela fonctionne, car l'heure à laquelle le temps ms commence est 00:00:00. Et comme tous les fuseaux horaires du monde changent par pas de 15 minutes, cela n'affecte pas l'arrondi aux quarts.

(Oups, j'ai eu un 0 de trop et oublié des parenthèses importantes : il est encore trop tôt)

0 votes

L'approche par la force brute rate des choses comme les secondes intercalaires. Bien que je sois d'accord qu'il doit y avoir beaucoup de secondes intercalaires pour faire une différence.

4 votes

Vous avez tout à fait raison, je n'ai pas tenu compte des secondes intercalaires. Cependant, la dernière fois que j'ai vérifié, il n'y avait pas de support pour les secondes intercalaires dans java.util.Date, donc les gens réglaient l'horloge de leur ordinateur pour qu'elle corresponde à l'heure du mur (ou à une horloge atomique) et la JVM calculait le mauvais début de l'époque (décalé du nombre de secondes intercalaires). Donc, en pratique, cela fonctionnerait et permettrait d'économiser un tas de code délicat, qui doit également gérer les secondes intercalaires. Conclusion : utilisez ntp pour synchroniser l'horloge de votre ordinateur.

3 votes

"tous les fuseaux horaires du monde changent par incréments de 30 minutes" - ce n'est pas vrai pour tous les fuseaux horaires. Il existe des fuseaux horaires qui utilisent des incréments de 15 minutes.

10voto

Lindhardt Points 31

C'est simple, trouvez le nombre de quaters depuis 1970 en double, arrondissez-le et multipliez-le par 15 minutes :

long timeMs = System.System.currentTimeMillis();

long roundedtimeMs = Math.round( (double)( (double)timeMs/(double)(15*60*1000) ) ) * (15*60*1000) );

Définissez votre objet Date ou Calendrier avec cela.

1 votes

Les parenthèses ne correspondent pas. Je pense que le code devrait être : long timeMs = System.currentTimeMillis(); long roundedtimeMs = Math.round( (double)timeMs/(15*60*1000) ) * (15*60*1000);

6voto

lboix Points 88

Merveilleux article, merci beaucoup les gars ! C'était exactement ce dont j'avais besoin :)

Voici mon code basé sur le travail de jour.

Mon cas d'utilisation est le suivant "Étant donné qu'il est 11h47, je veux définir deux dates symbolisant le cadre actuel de 5 minutes : 11h45 et 11h50".

            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            int modulo = calendar.get(Calendar.MINUTE) % 5;
            if(modulo > 0) {

                calendar.add(Calendar.MINUTE, -modulo);
            }

            myObject.setStartDate(calendar.getTime());

            calendar.add(Calendar.MINUTE, 5);
            myObject.setDueDate(calendar.getTime());

0 votes

J'ai obtenu un code soigné grâce à @Iboix. De petites modifications m'ont permis d'obtenir l'objet datetime requis.

3voto

Kandha Points 1305

vous pouvez utiliser ce simple code...

 int mode=min%15;
    if(mode>15/2){
     min=15-mode;
    }else{
     min=0-mode;
    }
    cal.add(Calendar.MINUTE, min);

1 votes

Merci pour l'indice d'où vient le 8 (15/2). cela m'a aidé à implémenter une version pour d'autres arrondissements comme 5 minutes et ainsi de suite !

0 votes

Un extrait concis et élégant. Fonctionne comme amélioration des solutions précédentes tout en manquant de contexte (où est min , cal définis) et l'explication.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X