Skip to content

Package: Zeitraum

Zeitraum

nameinstructionbranchcomplexitylinemethod
Zeitraum(LocalDateTime, LocalDateTime)
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
accept(AusschliessenderParameterVisitor)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
berechneUeberschneidung(Zeitraum)
M: 0 C: 36
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
contains(LocalDateTime)
M: 0 C: 24
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
contains(Zeitraum)
M: 0 C: 14
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
create(LocalDate, LocalDate)
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
create(LocalDateTime, ComparableQuantity)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
create(LocalDateTime, LocalDateTime)
M: 16 C: 10
38%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 1 C: 2
67%
M: 0 C: 1
100%
createWholeDay(LocalDate)
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
entferneZeitraeume(Collection)
M: 0 C: 48
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 11
100%
M: 0 C: 1
100%
equals(Object)
M: 2 C: 25
93%
M: 1 C: 5
83%
M: 1 C: 3
75%
M: 1 C: 7
88%
M: 0 C: 1
100%
getBis()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getDauer()
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getVon()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getWochentag()
M: 20 C: 12
38%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 1 C: 2
67%
M: 0 C: 1
100%
hashCode()
M: 0 C: 14
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
keineUeberschneidungAusserPunktuell(Zeitraum)
M: 0 C: 16
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
splitInEinzelneTage()
M: 0 C: 48
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
subtract(Zeitraum)
M: 0 C: 51
100%
M: 0 C: 10
100%
M: 0 C: 6
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
toString()
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
ueberschneidet(Zeitraum)
M: 0 C: 24
100%
M: 1 C: 7
88%
M: 1 C: 4
80%
M: 0 C: 4
100%
M: 0 C: 1
100%

Coverage

1: package zeit.eintraege;
2:
3: import auftraege.auftragsBildungsParameter.abstraction.AusschliessenderParameter;
4: import auftraege.auftragsBildungsParameter.abstraction.AusschliessenderParameterVisitor;
5: import tec.uom.se.ComparableQuantity;
6: import util.Constants;
7: import util.Immutable;
8: import util.exceptions.ExceptionConstants;
9: import zeit.ZeitUtils;
10:
11: import javax.measure.quantity.Time;
12: import java.time.DayOfWeek;
13: import java.time.LocalDate;
14: import java.time.LocalDateTime;
15: import java.time.LocalTime;
16: import java.util.Collection;
17: import java.util.Collections;
18: import java.util.HashSet;
19: import java.util.LinkedList;
20: import java.util.Optional;
21: import java.util.Set;
22:
23: /**
24: * Klasse welche einen Zeitraum mit einem festen Anfangspunkt und Endpunkt(bzw. implizite Dauer) darstellt.
25: */
26: @Immutable
27: public final class Zeitraum implements AusschliessenderParameter {
28:
29:         static final int BEFORE_MIDNIGHT_HOUR = 23;
30:         static final int BEFORE_MIDNIGHT_MINUTE = 59;
31:         static final int BEFORE_MIDNIGHT_SECOND = 59;
32:
33:         private final LocalDateTime von;
34:         private final LocalDateTime bis;
35:
36:         /**
37:          * Erstellt einen Zeitraum mit den gegebenen Werten.
38:          *
39:          * @param von
40:          *                 Beginn des Zeitraums
41:          * @param bis
42:          *                 Ende des Zeitraums
43:          */
44:         private Zeitraum(final LocalDateTime von, final LocalDateTime bis) {
45:                 this.von = von;
46:                 this.bis = bis;
47:         }
48:
49:         /**
50:          * Erstellt einen Zeitraum mit den gegebenen Werten.
51:          *
52:          * @param von
53:          *                 Beginn des Zeitraums
54:          * @param dauer
55:          *                 Dauer des Zeitraums
56:          *
57:          * @return einen Zeitraum vom Zeitpunkt von bis zum Zeitpunkt von+dauer
58:          */
59:         public static Zeitraum create(final LocalDateTime von, final ComparableQuantity<Time> dauer) {
60:                 return new Zeitraum(von, ZeitUtils.addTime(von, dauer));
61:         }
62:
63:
64:         /**
65:          * Erstellt einen Zeitraum mit den gegebenen Werten.
66:          *
67:          * @param von
68:          *                 Beginn des Zeitraums
69:          * @param bis
70:          *                 Ende des Zeitraums
71:          *
72:          * @return einen Zeitraum vom Zeitpunkt von bis zum Zeitpunkt bis
73:          */
74:         public static Zeitraum create(final LocalDateTime von, final LocalDateTime bis) {
75:•                if (von.isAfter(bis)) {
76:                         throw new IllegalArgumentException(String.format(ExceptionConstants.ENDE_VOR_ANFANG_ZEIT, von, bis));
77:                 }
78:                 return new Zeitraum(von, bis);
79:         }
80:
81:         /**
82:          * Erstellt einen Zeitraum mit den gegebenen Werten.
83:          *
84:          * @param von
85:          *                 Tag des Beginns des Zeitraums am Anfang des Tages.
86:          * @param bis
87:          *                 Tag des Endes des Zeitraums am Ende des Tages.
88:          *
89:          * @return einen Zeitraum vom Zeitpunkt von bis zum Zeitpunkt bis
90:          */
91:         public static Zeitraum create(final LocalDate von, final LocalDate bis) {
92:                 return Zeitraum.create(von.atStartOfDay(), bis.atTime(LocalTime.MAX));
93:         }
94:
95:         /**
96:          * @param tag
97:          *                 Tag den der Zeitraum komplett umfassen soll.
98:          *
99:          * @return einen Zeitraum, welcher den ganzen spezifizierten Tag umfasst (00:00-23:59).
100:          */
101:         public static Zeitraum createWholeDay(final LocalDate tag) {
102:                 return Zeitraum.create(tag.atStartOfDay(),
103:                                 tag.atTime(Zeitraum.BEFORE_MIDNIGHT_HOUR, Zeitraum.BEFORE_MIDNIGHT_MINUTE, Zeitraum.BEFORE_MIDNIGHT_SECOND));
104:         }
105:
106:         /**
107:          * @param zeitpunkt
108:          *                 Zeitpunkt
109:          *
110:          * @return true wenn der Zeitpunkt im Zeitraum enthalten ist.
111:          */
112:         public boolean contains(final LocalDateTime zeitpunkt) {
113:•                return this.getVon().isEqual(zeitpunkt) || this.getBis().isEqual(zeitpunkt)
114:•                                || (this.getBis().isAfter(zeitpunkt) && this.getVon().isBefore(zeitpunkt));
115:         }
116:
117:         /**
118:          * @param zeitraum
119:          *                 Zeitraum
120:          *
121:          * @return true wenn der andere Zeitraum in diesem Zeitraum vollständig enthalten ist.
122:          */
123:         public boolean contains(final Zeitraum zeitraum) {
124:•                return this.contains(zeitraum.getVon()) && this.contains(zeitraum.getBis());
125:         }
126:
127:         /**
128:          * @param zeitraum
129:          *                 definierter Zeitraum.
130:          *
131:          * @return true, falls es eine Überschneidung des Kalendereintrags mit dem definierten Zeitraum gibt.
132:          */
133:         public boolean ueberschneidet(final Zeitraum zeitraum) {
134:•                return this.contains(zeitraum.getVon())
135:•                                || this.contains(zeitraum.getBis())
136:•                                || zeitraum.contains(this.getVon())
137:•                                || zeitraum.contains(this.getBis());
138:         }
139:
140:         /**
141:          * @return Beginnzeitpunkt des Kalendereintrags
142:          */
143:         public LocalDateTime getVon() {
144:                 return this.von;
145:         }
146:
147:         /**
148:          * @return die Dauer des Kalendereintrags.
149:          */
150:         public ComparableQuantity<Time> getDauer() {
151:                 return ZeitUtils.calcTimeBetween(this.von, this.bis);
152:         }
153:
154:         /**
155:          * @return Endezeitpunkt des Kalendereintrags
156:          */
157:         public LocalDateTime getBis() {
158:                 return this.bis;
159:         }
160:
161:         /**
162:          * @param zeitraum
163:          *                 Zeitraum der abgezogen wird.
164:          *
165:          * @return Zeiträume die entstehen wenn man einen Zeitraum aus einem anderen Zeitraum herausnimmt. Es enstehen entweder 1, 2 oder kein neuer Zeitraum, falls die
166:          * Zeiträume sich garnicht überschneiden.
167:          */
168:         public Collection<Zeitraum> subtract(final Zeitraum zeitraum) {
169:•                if (zeitraum.contains(this) && !this.equals(zeitraum)) {
170:                         // Anderer Zeitraum umschließt komplett den this-Zeitraum;
171:                         return Collections.emptySet();
172:                 }
173:
174:•                if (this.keineUeberschneidungAusserPunktuell(zeitraum)) {
175:                         return Collections.singleton(this);
176:                 }
177:
178:                 final Collection<Zeitraum> zeitraeume = new HashSet<>();
179:
180:•                if (this.getVon().isBefore(zeitraum.getVon())) {
181:                         zeitraeume.add(Zeitraum.create(this.getVon(), zeitraum.getVon()));
182:                 }
183:
184:•                if (zeitraum.getBis().isBefore(this.getBis())) {
185:                         zeitraeume.add(Zeitraum.create(zeitraum.getBis(), this.getBis()));
186:                 }
187:
188:                 return zeitraeume;
189:         }
190:
191:         /**
192:          * @param zeitraum
193:          *                 Zeitraum mit dem auf eine nicht nur punktuelle Überschneidung getestet werden soll.
194:          *
195:          * @return true, wenn die Zeiträume sich punktuell oder garnicht überschneiden. Bswp. 8-12, 12-14 = true 8-12, 11-14 = false 8-12, 13-14 = true
196:          */
197:         public boolean keineUeberschneidungAusserPunktuell(final Zeitraum zeitraum) {
198:•                return zeitraum.getBis().isBefore(this.getVon()) || zeitraum.getVon().isAfter(this.getBis());
199:         }
200:
201:         /**
202:          * @param abwesenheiten
203:          *                 Zeiträume, welche Abwesenheiten repräsentieren, die entfernt werden sollen.
204:          *
205:          * @return Zeiträume, welche Teile des ursprünglichen Zeitraums sind, wobei die Zeiträume der Abwesenheiten hier fehlen.
206:          */
207:         public Set<Zeitraum> entferneZeitraeume(final Collection<Zeitraum> abwesenheiten) {
208:•                if (abwesenheiten.isEmpty()) {
209:                         return Collections.singleton(this);
210:                 }
211:                 final Set<Zeitraum> entstehendeZeitraeume = new HashSet<>();
212:
213:                 final Zeitraum abwesenheit = abwesenheiten.stream().findAny().get();
214:
215:                 final Collection<Zeitraum> neueZeitraeume = this.subtract(abwesenheit);
216:•                for (final Zeitraum neuerZeitraum : neueZeitraeume) {
217:
218:                         final HashSet<Zeitraum> abwesenheitenReduziert = new HashSet<>(abwesenheiten);
219:                         abwesenheitenReduziert.remove(abwesenheit);
220:
221:                         entstehendeZeitraeume.addAll(neuerZeitraum.entferneZeitraeume(abwesenheitenReduziert));
222:                 }
223:
224:                 return entstehendeZeitraeume;
225:         }
226:
227:         @Override
228:         public boolean equals(final Object o) {
229:•                if (this == o) {
230:                         return true;
231:                 }
232:•                if (!(o instanceof Zeitraum)) {
233:                         return false;
234:                 }
235:
236:                 final Zeitraum zeitraum = (Zeitraum) o;
237:
238:•                if (!this.von.equals(zeitraum.von)) {
239:                         return false;
240:                 }
241:                 return this.bis.equals(zeitraum.bis);
242:         }
243:
244:         @Override
245:         public int hashCode() {
246:                 int result = this.von.hashCode();
247:                 result = Constants.EINUNDDREISSIG * result + this.bis.hashCode();
248:                 return result;
249:         }
250:
251:         @Override
252:         public String toString() {
253: return "Zeitraum{" + "von=" + this.von
254: + ", bis=" + this.bis
255: + '}';
256:         }
257:
258:         @Override
259:         public <T> T accept(final AusschliessenderParameterVisitor<T> v) {
260:                 return v.handle(this);
261:         }
262:
263:         /**
264:          * @return erstellt eine Liste von Zeiträumen, wobei jeder Zeitraum einen sub-Zeitraum repräsentiert,
265: * z. B: für den Zeitraum von 16.02, 8:00 bis 20.02, 8:00 werden 5
266:          * Sub-Zeiträume erstellt:
267:          * <p>
268:          * 16.02 8:00 - 24:00
269:          * <p>
270:          * 17.02 0:00 - 24:00
271:          * <p>
272:          * 18.02 0:00 - 24:00
273:          * <p>
274:          * 19.02 0:00 - 8:00
275:          */
276:         public Collection<Zeitraum> splitInEinzelneTage() {
277:
278:                 Zeitraum zeitraum = Zeitraum.create(this.getVon(), this.getBis());
279:                 final Collection<Zeitraum> gelieferteZeitraeume = new LinkedList<>();
280:
281:                 // wenn "von-Tag" gleich "bis" Tag, denn Zeitraum in die Liste und return;
282:•                while (!zeitraum.getVon().toLocalDate().isEqual(zeitraum.getBis().toLocalDate())) {
283:                         zeitraum = Zeitraum.create(zeitraum.getVon(), zeitraum.getVon().toLocalDate().atTime(LocalTime.MAX));
284:                         gelieferteZeitraeume.add(zeitraum);
285:                         //getstartOfDay zu von +1
286:                         zeitraum = Zeitraum.create(zeitraum.getVon().plusDays(1).toLocalDate().atStartOfDay(), this.getBis());
287:                 }
288:                 gelieferteZeitraeume.add(zeitraum);
289:                 return gelieferteZeitraeume;
290:         }
291:
292:         /**
293:          * @return falls es sich um einen Zeitraum handelt, der nur einen Tag umspannt, wird der Wochentag dieses Tages geliefert.
294:          * @throws IllegalStateException
295:          *                 falls der Zeitraum über mehrere Tage geht, wird diese Exception geworfen.
296:          */
297:         public DayOfWeek getWochentag() {
298:•                if (this.getVon().getDayOfWeek().equals(this.getBis().getDayOfWeek())) {
299:                         return this.getVon().getDayOfWeek();
300:                 }
301:                 throw new IllegalStateException(String.format(ExceptionConstants.NICHT_DER_GLEICHE_TAG, this.getVon().toString(), this.getBis().toString()));
302:
303:         }
304:
305: /**
306: * @param zeitraum ein Zeitraum
307: * @return den Schnitt der beiden Zeiträume. Gibt es keinen Schnitt wird ein Empty Optional returned.
308: */
309: public Optional<Zeitraum> berechneUeberschneidung(final Zeitraum zeitraum) {
310:          final Zeitraum fruehererZeitraum;
311:          final Zeitraum spaetererZeitraum;
312:•         if (this.getVon().isBefore(zeitraum.getVon())) {
313: fruehererZeitraum = this;
314: spaetererZeitraum = zeitraum;
315: } else {
316: fruehererZeitraum = zeitraum;
317: spaetererZeitraum = this;
318: }
319:• if (fruehererZeitraum.getBis().isBefore(spaetererZeitraum.getVon()) || fruehererZeitraum.getBis().isEqual(spaetererZeitraum.getVon())) {
320:          return Optional.empty();
321: }
322: return Optional.of(Zeitraum.create(spaetererZeitraum.getVon(), fruehererZeitraum.getBis()));
323: }
324: }