2017-05-10 3 views
1

J'ai besoin d'aide s'il vous plaît, Comment puis-je calculer les heures d'ouverture entre deux dates? Par exemple, nous avons deux dates; 01/01/2017 10h00 et 04/01/2017 15h00. Et nous avons des heures de travail de 09h30 à 17h30 (8 heures) en semaine. Comment puis-je calculer les heures et les minutes de travail avec Java?Calculer uniquement les heures de travail entre deux dates excluant les week-ends en Java

Merci pour votre aide.

+2

Vous pouvez commencer ici https://docs.oracle.com/javase/tutorial/datetime/iso/index.html – nandsito

+0

La meilleure technique que j'ai lu à propos de ce genre de problème est de maintenir une base de données de dates, keyed par la date et contenant des colonnes pour tous les attributs d'intérêt, par exemple, 'isWeekday',' isWeekend', 'holidays' (une clé étrangère très probablement),' workingHours', etc. Ensuite, il est relativement simple de créer un ensemble de travail des enregistrements d'une requête SQL, suivi d'un léger traitement Java. –

+0

En relation: [Obtenir des minutes entre deux jours ouvrables en Java] (https://stackoverflow.com/questions/28995301/get-minutes-between-two-working-days-in-java). Et [Comment ajouter des heures d'affaires à ce jour en considérant ne pas ajouter des week-ends? - Java] (https://stackoverflow.com/questions/34943530/how-to-add-business-hours-to-date-considering-not-adding-weekends-java) aussi. –

Répondre

2

Sur le dessus de ma tête. Permettez-moi de vous suggérer de commencer par étudier le paquet java.time avec les sous-paquetages, l'API de date et d'heure Java moderne. Il ya an Oracle tutorial ainsi que d'autres bons matériels de lecture sur le net, allez chercher.

Ensuite, je voudrais séparer le modèle (domaine, couche de gestion) de l'interface (utilisateur). Je suppose que 01/01/2017 10:00 est une chaîne d'entrée de quelque part. Je compterais ceci comme interface. Dans votre modèle, vous voudrez utiliser des classes et des objets datetime pour vos données.

Pensez à la nécessité de prendre en compte le fuseau horaire et l'heure d'été (DST). Puisque les transitions d'heure d'été se produisent habituellement dans la nuit et non pendant les heures de travail, je ne pense pas, mais prenez votre propre décision. Si vous en avez besoin, comptez sur les objets ZonedDateTime, sinon LocalDateTime.

Je commencerais par écrire un bon test unitaire pour le calcul des heures de travail. Vous pouvez aussi en écrire un pour la conversion des chaînes d'entrée en LocalDateTime ou ZonedDateTime, mais il n'y aura pas besoin de beaucoup de tests ici.

J'utiliserais un DateTimeFormatter pour analyser vos deux valeurs datetime en LocalDateTime objets. Puis .atZone() si vous avez besoin de convertir en ZonedDateTime.

Modèle/calcul de l'heure de travail

Inspirée de this question Je pense que ce sera pratique pour régler le datetime début et la fin si elles tombent en dehors des heures de travail. Par exemple, si l'heure de début est le samedi à 3 heures du matin, déplacez-la au lundi au début de la journée de travail. Si l'heure de fin est le samedi 3 heures, déplacez-le au vendredi à la fin de la journée de travail. Vous aurez besoin de méthodes comme getDayOfWeek, toLocalDate, minusDays, plusDays et atTime en fonction de la façon exacte dont vous voulez faire cela. Vous pouvez également sauter cette étape, vous verrez plus tard si vous trouvez cela intéressant. Ou peut-être seulement déplacer l'heure du jour mais ne pas changer le jour.

Ensuite, vous avez besoin de l'ChronoUnit enum. Commencez par exemple par ChronoUnit.WEEKS.between(startDateTime, endDateTime) pour trouver le nombre de semaines complètes dans votre intervalle. Multipliez par le nombre d'heures de travail par semaine. Une option qui semble attrayante est de stocker les heures dans un objet Duration puisque je pense que nous aurons besoin d'un plus tard de toute façon. Ajoutez également les semaines à votre heure de début afin que vous disposiez d'un intervalle pour le temps de travail restant (jours et heures).

À ce stade, il devient de plus en plus compliqué, car vous devez vérifier si les jours sont des jours ouvrables et à la fin et l'heure de début de la journée de travail. La classe Duration peut être pratique pour additionner les heures, minutes et secondes de chaque jour de travail, du nouveau début date à la fin date/heure. Vous pouvez utiliser ses méthodes between et plus.Vous devrez probablement gérer le cas où le nouveau datetime start et le datetime fin tombent à la même date spécialement.

Vérifiez si cela ne vous permet pas de démarrer.