Coverage Report - de.jollyday.util.CalendarUtil
 
Classes in this File Line Coverage Branch Coverage Complexity
CalendarUtil
96%
56/58
95%
19/20
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  
 }