| 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 | } |