Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
CalendarUtil |
|
| 1.8461538461538463;1,846 |
1 | /** | |
2 | * Copyright 2010 Sven Diedrichsen | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an | |
12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | |
13 | * express or implied. See the License for the specific language | |
14 | * governing permissions and limitations under the License. | |
15 | */ | |
16 | package de.jollyday.util; | |
17 | ||
18 | import static java.time.DayOfWeek.SATURDAY; | |
19 | import static java.time.DayOfWeek.SUNDAY; | |
20 | import static java.time.Month.APRIL; | |
21 | import static java.time.Month.DECEMBER; | |
22 | import static java.time.Month.JANUARY; | |
23 | import static java.time.Month.MARCH; | |
24 | ||
25 | import java.time.LocalDate; | |
26 | import java.time.chrono.ChronoLocalDate; | |
27 | import java.time.chrono.Chronology; | |
28 | import java.time.chrono.HijrahChronology; | |
29 | import java.time.temporal.ChronoField; | |
30 | import java.util.Calendar; | |
31 | import java.util.HashSet; | |
32 | import java.util.Set; | |
33 | ||
34 | import org.threeten.extra.chrono.CopticChronology; | |
35 | import org.threeten.extra.chrono.JulianChronology; | |
36 | ||
37 | import de.jollyday.Holiday; | |
38 | import de.jollyday.config.Fixed; | |
39 | ||
40 | /** | |
41 | * Utility class for date operations. | |
42 | * | |
43 | * @author Sven Diedrichsen | |
44 | * @version $Id: $ | |
45 | */ | |
46 | 251 | public class CalendarUtil { |
47 | ||
48 | 251 | private XMLUtil xmlUtil = new XMLUtil(); |
49 | ||
50 | /** | |
51 | * Creates the current date within the gregorian calendar. | |
52 | * | |
53 | * @return today | |
54 | */ | |
55 | public LocalDate create() { | |
56 | 0 | return LocalDate.now(); |
57 | } | |
58 | ||
59 | /** | |
60 | * Creates the date within the ISO chronology. | |
61 | * | |
62 | * @param year | |
63 | * a int. | |
64 | * @param month | |
65 | * a int. | |
66 | * @param day | |
67 | * a int. | |
68 | * @return date | |
69 | */ | |
70 | public LocalDate create(int year, int month, int day) { | |
71 | 2526 | return LocalDate.of(year, month, day); |
72 | } | |
73 | ||
74 | /** | |
75 | * Creates the date within the provided chronology. | |
76 | * | |
77 | * @param year | |
78 | * a int. | |
79 | * @param month | |
80 | * a int. | |
81 | * @param day | |
82 | * a int. | |
83 | * @param chronology | |
84 | * the chronology to use | |
85 | * @return date the {@link LocalDate} | |
86 | */ | |
87 | public ChronoLocalDate create(int year, int month, int day, Chronology chronology) { | |
88 | 0 | return chronology.date(year, month, day); |
89 | } | |
90 | ||
91 | /** | |
92 | * Creates the date from the month/day within the specified year. | |
93 | * | |
94 | * @param year | |
95 | * a int. | |
96 | * @param fixed | |
97 | * a {@link de.jollyday.config.Fixed} object. | |
98 | * @return A local date instance. | |
99 | */ | |
100 | public LocalDate create(int year, Fixed fixed) { | |
101 | 2109 | return create(year, xmlUtil.getMonth(fixed.getMonth()), fixed.getDay()); |
102 | } | |
103 | ||
104 | /** | |
105 | * Creates a LocalDate. Does not use the Chronology of the Calendar. | |
106 | * | |
107 | * @param c | |
108 | * a {@link java.util.Calendar} object. | |
109 | * @return The local date representing the provided date. | |
110 | */ | |
111 | public LocalDate create(final Calendar c) { | |
112 | //TODO: javadoc needs updating | |
113 | 4 | return LocalDate.of(c.get(Calendar.YEAR), c.get(Calendar.MONTH) + 1, c |
114 | 2 | .get(Calendar.DAY_OF_MONTH)); |
115 | } | |
116 | ||
117 | /** | |
118 | * Returns the easter sunday for a given year. | |
119 | * | |
120 | * @param year | |
121 | * a int. | |
122 | * @return Easter sunday. | |
123 | */ | |
124 | public LocalDate getEasterSunday(int year) { | |
125 | 330 | if (year <= 1583) { |
126 | 1 | return getJulianEasterSunday(year); |
127 | } else { | |
128 | 329 | return getGregorianEasterSunday(year); |
129 | } | |
130 | } | |
131 | ||
132 | /** | |
133 | * Returns the easter sunday within the julian chronology. | |
134 | * | |
135 | * @param year | |
136 | * a int. | |
137 | * @return julian easter sunday | |
138 | */ | |
139 | public LocalDate getJulianEasterSunday(int year) { | |
140 | int a, b, c, d, e; | |
141 | int x, month, day; | |
142 | 4 | a = year % 4; |
143 | 4 | b = year % 7; |
144 | 4 | c = year % 19; |
145 | 4 | d = (19 * c + 15) % 30; |
146 | 4 | e = (2 * a + 4 * b - d + 34) % 7; |
147 | 4 | x = d + e + 114; |
148 | 4 | month = x / 31; |
149 | 4 | day = (x % 31) + 1; |
150 | 4 | return LocalDate.from(JulianChronology.INSTANCE.date(year, (month == 3 ? 3 : 4), day)); |
151 | } | |
152 | ||
153 | /** | |
154 | * Returns the easter sunday within the gregorian chronology. | |
155 | * | |
156 | * @param year | |
157 | * a int. | |
158 | * @return gregorian easter sunday. | |
159 | */ | |
160 | public LocalDate getGregorianEasterSunday(int year) { | |
161 | int a, b, c, d, e, f, g, h, i, j, k, l; | |
162 | int x, month, day; | |
163 | 337 | a = year % 19; |
164 | 337 | b = year / 100; |
165 | 337 | c = year % 100; |
166 | 337 | d = b / 4; |
167 | 337 | e = b % 4; |
168 | 337 | f = (b + 8) / 25; |
169 | 337 | g = (b - f + 1) / 3; |
170 | 337 | h = (19 * a + b - d - g + 15) % 30; |
171 | 337 | i = c / 4; |
172 | 337 | j = c % 4; |
173 | 337 | k = (32 + 2 * e + 2 * i - h - j) % 7; |
174 | 337 | l = (a + 11 * h + 22 * k) / 451; |
175 | 337 | x = h + k - 7 * l + 114; |
176 | 337 | month = x / 31; |
177 | 337 | day = (x % 31) + 1; |
178 | 337 | return LocalDate.of(year, (month == 3 ? MARCH : APRIL), day); |
179 | } | |
180 | ||
181 | /** | |
182 | * Returns if this date is on a wekkend. | |
183 | * | |
184 | * @param date | |
185 | * a {@link LocalDate} object. | |
186 | * @return is weekend | |
187 | */ | |
188 | public boolean isWeekend(final LocalDate date) { | |
189 | 4 | return date.getDayOfWeek() == SATURDAY || date.getDayOfWeek() == SUNDAY; |
190 | } | |
191 | ||
192 | /** | |
193 | * Returns a set of gregorian dates within a gregorian year which equal the | |
194 | * islamic month and day. Because the islamic year is about 11 days shorter | |
195 | * than the gregorian there may be more than one occurrence of an islamic | |
196 | * date in an gregorian year. i.e.: In the gregorian year 2008 there were | |
197 | * two 1/1. They occurred on 1/10 and 12/29. | |
198 | * | |
199 | * @param gregorianYear | |
200 | * a int. | |
201 | * @param islamicMonth | |
202 | * a int. | |
203 | * @param islamicDay | |
204 | * a int. | |
205 | * @return List of gregorian dates for the islamic month/day. | |
206 | */ | |
207 | public Set<LocalDate> getIslamicHolidaysInGregorianYear(int gregorianYear, int islamicMonth, int islamicDay) { | |
208 | 17 | return getDatesFromChronologyWithinGregorianYear(islamicMonth, islamicDay, gregorianYear, |
209 | HijrahChronology.INSTANCE); | |
210 | } | |
211 | ||
212 | /** | |
213 | * Returns a set of gregorian dates within a gregorian year which equal the | |
214 | * ethiopian orthodox month and day. Because the ethiopian orthodox year | |
215 | * different from the gregorian there may be more than one occurrence of an | |
216 | * ethiopian orthodox date in an gregorian year. | |
217 | * | |
218 | * @param gregorianYear | |
219 | * a int. | |
220 | * @return List of gregorian dates for the ethiopian orthodox month/day. | |
221 | * @param eoMonth | |
222 | * a int. | |
223 | * @param eoDay | |
224 | * a int. | |
225 | */ | |
226 | public Set<LocalDate> getEthiopianOrthodoxHolidaysInGregorianYear(int gregorianYear, int eoMonth, int eoDay) { | |
227 | 3 | return getDatesFromChronologyWithinGregorianYear(eoMonth, eoDay, gregorianYear, CopticChronology.INSTANCE); |
228 | } | |
229 | ||
230 | /** | |
231 | * Searches for the occurrences of a month/day in one chronology within one | |
232 | * gregorian year. | |
233 | * | |
234 | * @param targetMonth | |
235 | * @param targetDay | |
236 | * @param gregorianYear | |
237 | * @param targetChrono | |
238 | * @return the list of gregorian dates. | |
239 | */ | |
240 | private Set<LocalDate> getDatesFromChronologyWithinGregorianYear(int targetMonth, int targetDay, int gregorianYear, | |
241 | Chronology targetChrono) { | |
242 | 20 | Set<LocalDate> holidays = new HashSet<>(); |
243 | 20 | LocalDate firstGregorianDate = LocalDate.of(gregorianYear, JANUARY, 1); |
244 | 20 | LocalDate lastGregorianDate = LocalDate.of(gregorianYear, DECEMBER, 31); |
245 | ||
246 | 20 | ChronoLocalDate firstTargetDate = targetChrono.date(firstGregorianDate); |
247 | 20 | ChronoLocalDate lastTargetDate = targetChrono.date(lastGregorianDate); |
248 | ||
249 | 20 | int targetYear = firstTargetDate.get(ChronoField.YEAR); |
250 | 20 | final int lastYear = lastTargetDate.get(ChronoField.YEAR); |
251 | ||
252 | 63 | for (; targetYear <= lastYear;) { |
253 | 43 | ChronoLocalDate d = targetChrono.date(targetYear, targetMonth, targetDay); |
254 | 43 | if (!firstGregorianDate.isAfter(d) && !lastGregorianDate.isBefore(d)) { |
255 | 22 | holidays.add(LocalDate.from(d)); |
256 | } | |
257 | 43 | targetYear++; |
258 | 43 | } |
259 | 20 | return holidays; |
260 | } | |
261 | ||
262 | /** | |
263 | * Shows if the requested dat is contained in the Set of holidays. | |
264 | * | |
265 | * @param holidays | |
266 | * a {@link java.util.Set} object. | |
267 | * @param date | |
268 | * a {@link LocalDate} object. | |
269 | * @return contains this date | |
270 | */ | |
271 | public boolean contains(final Set<Holiday> holidays, final LocalDate date) { | |
272 | 2439 | for (Holiday h : holidays) { |
273 | 18459 | if (h.getDate().equals(date)) { |
274 | 1371 | return true; |
275 | } | |
276 | 17089 | } |
277 | 1070 | return false; |
278 | } | |
279 | ||
280 | } |