1
|
package data;
|
2
|
|
3
|
import java.time.LocalDate;
|
4
|
import java.time.ZoneId;
|
5
|
import java.time.temporal.ChronoUnit;
|
6
|
import java.util.Arrays;
|
7
|
import java.util.Calendar;
|
8
|
import java.util.Date;
|
9
|
|
10
|
//------ TO-DO LIST ----
|
11
|
// TODO: 04.05.2019 JavaDoc - Dokumentace
|
12
|
|
13
|
/**
|
14
|
*
|
15
|
* Trida uchovavajici informace a umoznujici praci s bitmapou
|
16
|
*
|
17
|
* @author Daniel Stus, Marek Sobota, Lukas Scurko, Jan Jirman
|
18
|
* @version 0.8
|
19
|
*
|
20
|
*/
|
21
|
public class Bitmap {
|
22
|
|
23
|
//-------------- Atributy --------------/
|
24
|
|
25
|
/** Atribut - Datum zacatku obdobi */
|
26
|
private Calendar dateFrom;
|
27
|
|
28
|
/** Atribut - Datum konce obdobi */
|
29
|
private Calendar dateTo;
|
30
|
|
31
|
/** Atribut s cislem linky pro kterou je generovana bitmapa */
|
32
|
private String lineNumber;
|
33
|
|
34
|
/** Pole uchovavajici bitmapu */
|
35
|
private int[] bitmap;
|
36
|
|
37
|
private Calendar goodFriday, easterMonday;
|
38
|
|
39
|
|
40
|
|
41
|
//-------------- Konstruktor -------------/
|
42
|
|
43
|
/**
|
44
|
* Konstruktor incializuje a nastavuje důležité parametry tridy (@code Bitmap)
|
45
|
*
|
46
|
* @param dateFrom Datum zacatku obdobi
|
47
|
* @param dateTo Datum konce obdobi
|
48
|
* @param lineNumber Cislo linky
|
49
|
*/
|
50
|
public Bitmap(Calendar dateFrom, Calendar dateTo, String lineNumber) {
|
51
|
this.dateFrom = dateFrom;
|
52
|
this.dateTo = dateTo;
|
53
|
this.lineNumber = lineNumber;
|
54
|
this.bitmap = new int[(int) getDateRange()];
|
55
|
getEasterHolidays(dateFrom.get(Calendar.YEAR));
|
56
|
}
|
57
|
|
58
|
|
59
|
//----------------- Metody ----------------/
|
60
|
|
61
|
/**
|
62
|
* Metoda vrací počet dní uživatelem zvoleného období
|
63
|
*
|
64
|
* @return Počet dní v uživatelem zvoleném období (rozmezí)
|
65
|
*/
|
66
|
public long getDateRange() {
|
67
|
LocalDate from = this.dateFrom.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
68
|
LocalDate to = this.dateTo.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
69
|
|
70
|
long noOfDaysBetween = ChronoUnit.DAYS.between(from, to);
|
71
|
return noOfDaysBetween+1;
|
72
|
}
|
73
|
|
74
|
public long getDatePosition(Calendar date) {
|
75
|
LocalDate from = this.dateFrom.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
76
|
LocalDate to = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
77
|
|
78
|
long datePosition = ChronoUnit.DAYS.between(from, to);
|
79
|
//Re #7443
|
80
|
return datePosition;
|
81
|
}
|
82
|
|
83
|
|
84
|
public void setWorkdays(int value) {
|
85
|
value = validateValue(value);
|
86
|
Calendar currentDay = (Calendar) this.dateFrom.clone();
|
87
|
|
88
|
for (int i = 0; i < this.bitmap.length; i++) {
|
89
|
if (currentDay.get(Calendar.DAY_OF_WEEK) != 7 && currentDay.get(Calendar.DAY_OF_WEEK) != 1 && !isBankHoliday(currentDay)) {
|
90
|
this.bitmap[i] = value;
|
91
|
}
|
92
|
|
93
|
currentDay.add(Calendar.DATE, 1);
|
94
|
}
|
95
|
}
|
96
|
|
97
|
public void setSundaysAndHolidays(int value) {
|
98
|
value = validateValue(value);
|
99
|
Calendar currentDay = (Calendar) this.dateFrom.clone();
|
100
|
|
101
|
for (int i = 0; i < this.bitmap.length; i++) {
|
102
|
if (currentDay.get(Calendar.DAY_OF_WEEK) != 7) {
|
103
|
this.bitmap[i] = value;
|
104
|
}
|
105
|
|
106
|
currentDay.add(Calendar.DATE, 1);
|
107
|
}
|
108
|
}
|
109
|
|
110
|
public void setDay(Calendar day, int value) {
|
111
|
value = validateValue(value);
|
112
|
int dayPosition = (int) getDatePosition(day);
|
113
|
|
114
|
bitmap[dayPosition] = value;
|
115
|
}
|
116
|
|
117
|
|
118
|
public void setOneDayOnly(Calendar day) {
|
119
|
fillWithZeros();
|
120
|
int dayPosition = (int) getDatePosition(day);
|
121
|
|
122
|
bitmap[dayPosition] = 1;
|
123
|
}
|
124
|
|
125
|
public void setDaysInRange(Calendar from, Calendar to, int value) {
|
126
|
value = validateValue(value);
|
127
|
Calendar currentDay = (Calendar) this.dateFrom.clone();
|
128
|
to.add(Calendar.DATE, 1);
|
129
|
from.add(Calendar.DATE, -1);
|
130
|
|
131
|
for (int i = 0; i < this.bitmap.length; i++) {
|
132
|
if (currentDay.after(from) && currentDay.before(to) && !isBankHoliday(currentDay)) {
|
133
|
this.bitmap[i] = value;
|
134
|
}
|
135
|
|
136
|
currentDay.add(Calendar.DATE, 1);
|
137
|
}
|
138
|
|
139
|
}
|
140
|
|
141
|
public void setDaysInWeek(int dayNumber, int value) {
|
142
|
value = validateValue(value);
|
143
|
Calendar currentDay = (Calendar) this.dateFrom.clone();
|
144
|
|
145
|
for (int i = 0; i < this.bitmap.length; i++) {
|
146
|
if (currentDay.get(Calendar.DAY_OF_WEEK) == dayNumber) {
|
147
|
this.bitmap[i] = value;
|
148
|
}
|
149
|
|
150
|
currentDay.add(Calendar.DATE, 1);
|
151
|
}
|
152
|
}
|
153
|
|
154
|
public void setWeeks(int value, int remainder) {
|
155
|
value = validateValue(value);
|
156
|
Calendar currentDay = (Calendar) this.dateFrom.clone();
|
157
|
|
158
|
for (int i = 0; i < this.bitmap.length; i++) {
|
159
|
if ((currentDay.get(Calendar.WEEK_OF_YEAR)%2)==remainder) {
|
160
|
this.bitmap[i] = value;
|
161
|
}
|
162
|
|
163
|
currentDay.add(Calendar.DATE, 1);
|
164
|
|
165
|
}
|
166
|
}
|
167
|
|
168
|
public void setWeeks(int value, int remainder, int dayNumber) {
|
169
|
value = validateValue(value);
|
170
|
Calendar currentDay = (Calendar) this.dateFrom.clone();
|
171
|
|
172
|
for (int i = 0; i < this.bitmap.length; i++) {
|
173
|
if ((currentDay.get(Calendar.WEEK_OF_YEAR)%2) == remainder && currentDay.get((Calendar.DAY_OF_WEEK)) == dayNumber) {
|
174
|
this.bitmap[i] = value;
|
175
|
}
|
176
|
|
177
|
currentDay.add(Calendar.DATE, 1);
|
178
|
|
179
|
}
|
180
|
}
|
181
|
|
182
|
|
183
|
public void setWeeksRange(Calendar from, Calendar to, int value, int remainder) {
|
184
|
|
185
|
value = validateValue(value);
|
186
|
Calendar currentDay = (Calendar) this.dateFrom.clone();
|
187
|
to.add(Calendar.DATE, 1);
|
188
|
from.add(Calendar.DATE, -1);
|
189
|
|
190
|
for (int i = 0; i < this.bitmap.length; i++) {
|
191
|
if (currentDay.after(from) && currentDay.before(to)) {
|
192
|
if ((currentDay.get(Calendar.WEEK_OF_YEAR)%2)==remainder) {
|
193
|
this.bitmap[i] = value;
|
194
|
}
|
195
|
}
|
196
|
|
197
|
currentDay.add(Calendar.DATE, 1);
|
198
|
}
|
199
|
|
200
|
}
|
201
|
|
202
|
public void setWeeksRange(Calendar from, Calendar to, int value, int remainder, int dayNumber) {
|
203
|
|
204
|
value = validateValue(value);
|
205
|
Calendar currentDay = (Calendar) this.dateFrom.clone();
|
206
|
to.add(Calendar.DATE, 1);
|
207
|
from.add(Calendar.DATE, -1);
|
208
|
|
209
|
for (int i = 0; i < this.bitmap.length; i++) {
|
210
|
if (currentDay.after(from) && currentDay.before(to)) {
|
211
|
if ((currentDay.get(Calendar.WEEK_OF_YEAR)%2)==remainder && currentDay.get((Calendar.DAY_OF_WEEK)) == dayNumber) {
|
212
|
this.bitmap[i] = value;
|
213
|
}
|
214
|
}
|
215
|
|
216
|
currentDay.add(Calendar.DATE, 1);
|
217
|
}
|
218
|
|
219
|
}
|
220
|
|
221
|
public void unsetHolidays() {
|
222
|
Calendar currentDay = (Calendar) this.dateFrom.clone();
|
223
|
|
224
|
for (int i = 0; i < this.bitmap.length; i++) {
|
225
|
if (isBankHoliday(currentDay)) {
|
226
|
this.bitmap[i] = 0;
|
227
|
}
|
228
|
|
229
|
currentDay.add(Calendar.DATE, 1);
|
230
|
}
|
231
|
}
|
232
|
|
233
|
|
234
|
/**
|
235
|
* Metoda naplní (přemaže) bitmapu nulami
|
236
|
*/
|
237
|
public void fillWithZeros() {
|
238
|
Arrays.fill(this.bitmap, 0);
|
239
|
}
|
240
|
|
241
|
/**
|
242
|
* Metoda overuje spravnost zadane hodnoty
|
243
|
* - do bitmapy lze zadat pouze 1 nebo 0
|
244
|
* - v pripade ze uzivatel zada cislo vetsi nez jedna metoda vrati jednotku
|
245
|
* - v pripade ze uzivatel zada cislo mensi nez nula metoda vrati nulu
|
246
|
*
|
247
|
* @param value Uzivatelem zadana hodnota
|
248
|
* @return Nova (spravna hodnota) ukladajici se do bitmapy
|
249
|
*/
|
250
|
public static int validateValue(int value) {
|
251
|
if (value < 0) value = 0;
|
252
|
else if (value > 0) value = 1;
|
253
|
else return value;
|
254
|
return value;
|
255
|
}
|
256
|
|
257
|
public boolean isBankHoliday(Calendar cal) {
|
258
|
|
259
|
int month = cal.get(Calendar.MONTH);
|
260
|
int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
|
261
|
|
262
|
// 1. ledna - Den obnovy samostatného českého státu | Nový rok
|
263
|
if(month == Calendar.JANUARY && dayOfMonth == 1) {
|
264
|
return true;
|
265
|
}
|
266
|
|
267
|
// 1. ledna - Den obnovy samostatného českého státu | Nový rok
|
268
|
if(month == Calendar.JANUARY && dayOfMonth == 1) {
|
269
|
return true;
|
270
|
}
|
271
|
|
272
|
// Velikonoční pondělí
|
273
|
if(month == easterMonday.get(Calendar.MONTH) && dayOfMonth == easterMonday.get(Calendar.DAY_OF_MONTH)){
|
274
|
return true;
|
275
|
}
|
276
|
|
277
|
// Velký pátek
|
278
|
if(month == goodFriday.get(Calendar.MONTH) && dayOfMonth == goodFriday.get(Calendar.DAY_OF_MONTH)){
|
279
|
return true;
|
280
|
}
|
281
|
|
282
|
// 1. května - Svátek práce
|
283
|
if(month == Calendar.MAY && dayOfMonth == 1) {
|
284
|
return true;
|
285
|
}
|
286
|
|
287
|
// 8. května - Den vítězství
|
288
|
if(month == Calendar.MAY && dayOfMonth == 8) {
|
289
|
return true;
|
290
|
}
|
291
|
|
292
|
// 5. července - Den slovanských věrozvěstů Cyrila a Metoděje
|
293
|
if(month == Calendar.JULY && dayOfMonth == 5) {
|
294
|
return true;
|
295
|
}
|
296
|
|
297
|
// 6. července - Den upálení mistra Jana Husa
|
298
|
if(month == Calendar.JULY && dayOfMonth == 6) {
|
299
|
return true;
|
300
|
}
|
301
|
|
302
|
// 28. září – Den české státnosti
|
303
|
if(month == Calendar.SEPTEMBER && dayOfMonth == 28) {
|
304
|
return true;
|
305
|
}
|
306
|
|
307
|
// 28. října – Den vzniku samostatného československého státu
|
308
|
if(month == Calendar.OCTOBER && dayOfMonth == 28) {
|
309
|
return true;
|
310
|
}
|
311
|
|
312
|
// 17. listopadu – Den boje za svobodu a demokracii
|
313
|
if(month == Calendar.NOVEMBER && dayOfMonth == 17) {
|
314
|
return true;
|
315
|
}
|
316
|
|
317
|
// 24. prosince – Štědrý den
|
318
|
if(month == Calendar.DECEMBER && dayOfMonth == 24) {
|
319
|
return true;
|
320
|
}
|
321
|
|
322
|
// 25. prosince – 1. svátek vánoční
|
323
|
if(month == Calendar.DECEMBER && dayOfMonth == 25) {
|
324
|
return true;
|
325
|
}
|
326
|
|
327
|
// 26. prosince – 2. svátek vánoční
|
328
|
if(month == Calendar.DECEMBER && dayOfMonth == 26) {
|
329
|
return true;
|
330
|
}
|
331
|
|
332
|
// Není svátek
|
333
|
return false;
|
334
|
|
335
|
}
|
336
|
|
337
|
public void getEasterHolidays(int year) {
|
338
|
int Y = year;
|
339
|
int a = Y % 19;
|
340
|
int b = Y / 100;
|
341
|
int c = Y % 100;
|
342
|
int d = b / 4;
|
343
|
int e = b % 4;
|
344
|
int f = (b + 8) / 25;
|
345
|
int g = (b - f + 1) / 3;
|
346
|
int h = (19 * a + b - d - g + 15) % 30;
|
347
|
int i = c / 4;
|
348
|
int k = c % 4;
|
349
|
int L = (32 + 2 * e + 2 * i - h - k) % 7;
|
350
|
int m = (a + 11 * h + 22 * L) / 451;
|
351
|
int n = h + L - 7 * m + 114;
|
352
|
int month = n / 31;
|
353
|
int day = (n % 31) + 1;
|
354
|
|
355
|
Calendar easterMonday = Calendar.getInstance();
|
356
|
//Velikonoční pondělí --> Velikonoční neděle + 1
|
357
|
easterMonday.setTime(new Date(year-1900, month-1, day+1));
|
358
|
//Velký pátek --> Velikonoční neděle - 2
|
359
|
Calendar goodFriday = Calendar.getInstance();
|
360
|
goodFriday.setTime(new Date(year-1900, month-1, day-2));
|
361
|
|
362
|
this.easterMonday = easterMonday;
|
363
|
this.goodFriday = goodFriday;
|
364
|
}
|
365
|
|
366
|
public String getBitmapString() {
|
367
|
return Arrays.toString(this.bitmap).replaceAll("\\[|\\]|,|\\s", "");
|
368
|
}
|
369
|
|
370
|
public Calendar getDateFrom() {
|
371
|
return dateFrom;
|
372
|
}
|
373
|
|
374
|
public void setDateFrom(Calendar dateFrom) {
|
375
|
this.dateFrom = dateFrom;
|
376
|
}
|
377
|
|
378
|
public Calendar getDateTo() {
|
379
|
return dateTo;
|
380
|
}
|
381
|
|
382
|
public void setDateTo(Calendar dateTo) {
|
383
|
this.dateTo = dateTo;
|
384
|
}
|
385
|
|
386
|
public String getLineNumber() {
|
387
|
return lineNumber;
|
388
|
}
|
389
|
|
390
|
public void setLineNumber(String lineNumber) {
|
391
|
this.lineNumber = lineNumber;
|
392
|
}
|
393
|
|
394
|
public int[] getBitmap() {
|
395
|
return bitmap;
|
396
|
}
|
397
|
|
398
|
public void setBitmap(int[] bitmap) {
|
399
|
this.bitmap = bitmap;
|
400
|
}
|
401
|
|
402
|
@Override
|
403
|
public String toString() {
|
404
|
return Arrays.toString(this.bitmap);
|
405
|
}
|
406
|
|
407
|
|
408
|
/**
|
409
|
*
|
410
|
* hlavni metoda pro ozkouseni funkcnosti {@code Bitmap}
|
411
|
*-issue #7374
|
412
|
*
|
413
|
* @param args parametry programu
|
414
|
*/
|
415
|
public static void main(String[] args) {
|
416
|
|
417
|
Calendar dateFrom = Calendar.getInstance();
|
418
|
Calendar dateTo = Calendar.getInstance();
|
419
|
dateFrom.setTime(new Date(2019-1900, 4, 1)); // -- Jen pro testování Deprecated --
|
420
|
dateTo.setTime(new Date(2019-1900, 4, 31)); // rok udáván od 1900, měsíc se počítá od 0
|
421
|
|
422
|
|
423
|
Bitmap bitmap = new Bitmap(dateFrom, dateTo, "143440");
|
424
|
|
425
|
|
426
|
// ------------- KONTROLNÍ VÝPISY -----------------
|
427
|
System.out.println("------------- KONTROLNÍ VÝPISY -----------------");
|
428
|
System.out.println("Linka: "+ bitmap.getLineNumber());
|
429
|
System.out.println("Datum: od: " + bitmap.getDateFrom().getTime() + " | do: " + bitmap.getDateTo().getTime());
|
430
|
System.out.println("První den je: "+bitmap.getDateFrom().get(Calendar.DAY_OF_WEEK) + " (1 - Neděle; 2 - Pondělí; 3 - Úterý; 4 - Středa; 5 - Čtvrtek; 6 - Pátek; 7 - Sobota)");
|
431
|
System.out.println("Počet dní v rozmezí: " + bitmap.getDateRange());
|
432
|
System.out.println(bitmap.toString());
|
433
|
|
434
|
//Jede pouze v pracovní dny
|
435
|
bitmap.setWorkdays(1);
|
436
|
System.out.println("\nJede v pracovní dny:");
|
437
|
System.out.println(bitmap.toString());
|
438
|
|
439
|
bitmap.fillWithZeros();
|
440
|
|
441
|
bitmap.setSundaysAndHolidays(1);
|
442
|
System.out.println(bitmap.toString());
|
443
|
|
444
|
// Kontrola přemazání
|
445
|
System.out.println("\nKontrola přemazání:");
|
446
|
bitmap.fillWithZeros();
|
447
|
System.out.println(bitmap.toString());
|
448
|
|
449
|
//Nastavit pouze Pondělky - atribut 2
|
450
|
System.out.println("\nJede každé pondělí:");
|
451
|
bitmap.setDaysInWeek(2, 1);
|
452
|
System.out.println(bitmap.toString());
|
453
|
|
454
|
//přemazání
|
455
|
bitmap.fillWithZeros();
|
456
|
|
457
|
Calendar dateTo2 = Calendar.getInstance();
|
458
|
dateTo2.setTime(new Date(2019-1900, 4, 13));
|
459
|
bitmap.setWeeksRange(dateFrom, dateTo2, 1, 1);
|
460
|
System.out.println(bitmap.toString());
|
461
|
|
462
|
//Nastavit liché týdny (zbytek(remainder) 1 - liché)
|
463
|
System.out.println("\nLiché týdny:");
|
464
|
bitmap.setWeeks(1, 1);
|
465
|
System.out.println(bitmap.toString());
|
466
|
|
467
|
//Velikonoce pro svátky
|
468
|
System.out.println("Velikonoční pondělí: " + bitmap.easterMonday.getTime());
|
469
|
System.out.println("Velký pátek: " + bitmap.goodFriday.getTime());
|
470
|
|
471
|
|
472
|
}
|
473
|
|
474
|
|
475
|
}
|