You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

WorkDuration.java 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2021 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.api.impl.utils;
  21. import java.io.Serializable;
  22. import javax.annotation.Nullable;
  23. import org.apache.commons.lang.builder.ToStringBuilder;
  24. import org.apache.commons.lang.builder.ToStringStyle;
  25. /**
  26. * @since 4.2
  27. */
  28. public class WorkDuration implements Serializable {
  29. static final int DAY_POSITION_IN_LONG = 10_000;
  30. static final int HOUR_POSITION_IN_LONG = 100;
  31. static final int MINUTE_POSITION_IN_LONG = 1;
  32. public enum UNIT {
  33. DAYS, HOURS, MINUTES
  34. }
  35. private int hoursInDay;
  36. private long durationInMinutes;
  37. private int days;
  38. private int hours;
  39. private int minutes;
  40. private WorkDuration(long durationInMinutes, int days, int hours, int minutes, int hoursInDay) {
  41. this.durationInMinutes = durationInMinutes;
  42. this.days = days;
  43. this.hours = hours;
  44. this.minutes = minutes;
  45. this.hoursInDay = hoursInDay;
  46. }
  47. public static WorkDuration create(int days, int hours, int minutes, int hoursInDay) {
  48. long durationInSeconds = 60L * days * hoursInDay;
  49. durationInSeconds += 60L * hours;
  50. durationInSeconds += minutes;
  51. return new WorkDuration(durationInSeconds, days, hours, minutes, hoursInDay);
  52. }
  53. public static WorkDuration createFromValueAndUnit(int value, UNIT unit, int hoursInDay) {
  54. switch (unit) {
  55. case DAYS:
  56. return create(value, 0, 0, hoursInDay);
  57. case HOURS:
  58. return create(0, value, 0, hoursInDay);
  59. case MINUTES:
  60. return create(0, 0, value, hoursInDay);
  61. default:
  62. throw new IllegalStateException("Cannot create work duration");
  63. }
  64. }
  65. static WorkDuration createFromLong(long duration, int hoursInDay) {
  66. int days = 0;
  67. int hours = 0;
  68. int minutes = 0;
  69. long time = duration;
  70. long currentTime = time / WorkDuration.DAY_POSITION_IN_LONG;
  71. if (currentTime > 0) {
  72. days = (int) currentTime;
  73. time = time - (currentTime * WorkDuration.DAY_POSITION_IN_LONG);
  74. }
  75. currentTime = time / WorkDuration.HOUR_POSITION_IN_LONG;
  76. if (currentTime > 0) {
  77. hours = (int) currentTime;
  78. time = time - (currentTime * WorkDuration.HOUR_POSITION_IN_LONG);
  79. }
  80. currentTime = time / WorkDuration.MINUTE_POSITION_IN_LONG;
  81. if (currentTime > 0) {
  82. minutes = (int) currentTime;
  83. }
  84. return WorkDuration.create(days, hours, minutes, hoursInDay);
  85. }
  86. static WorkDuration createFromMinutes(long duration, int hoursInDay) {
  87. int days = (int)(duration / (double)hoursInDay / 60.0);
  88. long currentDurationInMinutes = duration - (60L * days * hoursInDay);
  89. int hours = (int)(currentDurationInMinutes / 60.0);
  90. currentDurationInMinutes = currentDurationInMinutes - (60L * hours);
  91. return new WorkDuration(duration, days, hours, (int) currentDurationInMinutes, hoursInDay);
  92. }
  93. /**
  94. * Return the duration in number of working days.
  95. * For instance, 3 days and 4 hours will return 3.5 days (if hoursIndDay is 8).
  96. */
  97. public double toWorkingDays() {
  98. return durationInMinutes / 60D / hoursInDay;
  99. }
  100. /**
  101. * Return the duration using the following format DDHHMM, where DD is the number of days, HH is the number of months, and MM the number of minutes.
  102. * For instance, 3 days and 4 hours will return 030400 (if hoursIndDay is 8).
  103. */
  104. public long toLong() {
  105. int workingDays = days;
  106. int workingHours = hours;
  107. if (hours >= hoursInDay) {
  108. int nbAdditionalDays = hours / hoursInDay;
  109. workingDays += nbAdditionalDays;
  110. workingHours = hours - (nbAdditionalDays * hoursInDay);
  111. }
  112. return 1L * workingDays * DAY_POSITION_IN_LONG + workingHours * HOUR_POSITION_IN_LONG + minutes * MINUTE_POSITION_IN_LONG;
  113. }
  114. public long toMinutes() {
  115. return durationInMinutes;
  116. }
  117. public WorkDuration add(@Nullable WorkDuration with) {
  118. if (with != null) {
  119. return WorkDuration.createFromMinutes(this.toMinutes() + with.toMinutes(), this.hoursInDay);
  120. } else {
  121. return this;
  122. }
  123. }
  124. public WorkDuration subtract(@Nullable WorkDuration with) {
  125. if (with != null) {
  126. return WorkDuration.createFromMinutes(this.toMinutes() - with.toMinutes(), this.hoursInDay);
  127. } else {
  128. return this;
  129. }
  130. }
  131. public WorkDuration multiply(int factor) {
  132. return WorkDuration.createFromMinutes(this.toMinutes() * factor, this.hoursInDay);
  133. }
  134. public int days() {
  135. return days;
  136. }
  137. public int hours() {
  138. return hours;
  139. }
  140. public int minutes() {
  141. return minutes;
  142. }
  143. int hoursInDay() {
  144. return hoursInDay;
  145. }
  146. @Override
  147. public boolean equals(Object o) {
  148. if (this == o) {
  149. return true;
  150. }
  151. if (o == null || getClass() != o.getClass()) {
  152. return false;
  153. }
  154. WorkDuration that = (WorkDuration) o;
  155. return durationInMinutes == that.durationInMinutes;
  156. }
  157. @Override
  158. public int hashCode() {
  159. return (int) (durationInMinutes ^ (durationInMinutes >>> 32));
  160. }
  161. @Override
  162. public String toString() {
  163. return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
  164. }
  165. }