Java tutorial
/** * Copyright 2010 Sven Diedrichsen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package com.jjlharrison.jollyday.util; import java.util.Calendar; import java.util.HashSet; import java.util.Set; import com.jjlharrison.jollyday.Holiday; import org.joda.time.Chronology; import org.joda.time.DateTimeConstants; import org.joda.time.Interval; import org.joda.time.LocalDate; import org.joda.time.chrono.CopticChronology; import org.joda.time.chrono.ISOChronology; import org.joda.time.chrono.IslamicChronology; import org.joda.time.chrono.JulianChronology; import com.jjlharrison.config.Fixed; /** * Utility class for date operations. * * @author Sven Diedrichsen * @version $Id: $ */ public class CalendarUtil { private XMLUtil xmlUtil = new XMLUtil(); /** * Creates the current date within the gregorian calendar. * * @return today */ public LocalDate create() { return new LocalDate(ISOChronology.getInstance()); } /** * Creates the date within the ISO chronology. * * @param year * a int. * @param month * a int. * @param day * a int. * @return date */ public LocalDate create(int year, int month, int day) { return create(year, month, day, ISOChronology.getInstance()); } /** * Creates the date within the provided chronology. * * @param year * a int. * @param month * a int. * @param day * a int. * @param chronology * the chronology to use * @return date the {@link LocalDate} */ public LocalDate create(int year, int month, int day, Chronology chronology) { return new LocalDate(year, month, day, chronology); } /** * Creates the date from the month/day within the specified year. * * @param year * a int. * @param fixed * a {@link com.jjlharrison.config.Fixed} object. * @return A local date instance. */ public LocalDate create(int year, Fixed fixed) { return create(year, xmlUtil.getMonth(fixed.getMonth()), fixed.getDay()); } /** * Creates a LocalDate. Does not use the Chronology of the Calendar. * * @param c * a {@link java.util.Calendar} object. * @return The local date representing the provided date. */ public LocalDate create(final Calendar c) { return new LocalDate(c, ISOChronology.getInstance()); } /** * Returns the easter sunday for a given year. * * @param year * a int. * @return Easter sunday. */ public LocalDate getEasterSunday(int year) { if (year <= 1583) { return getJulianEasterSunday(year); } else { return getGregorianEasterSunday(year); } } /** * Returns the easter sunday within the julian chronology. * * @param year * a int. * @return julian easter sunday */ public LocalDate getJulianEasterSunday(int year) { int a, b, c, d, e; int x, month, day; a = year % 4; b = year % 7; c = year % 19; d = (19 * c + 15) % 30; e = (2 * a + 4 * b - d + 34) % 7; x = d + e + 114; month = x / 31; day = (x % 31) + 1; LocalDate julianEasterDate = create(year, (month == 3 ? DateTimeConstants.MARCH : DateTimeConstants.APRIL), day, JulianChronology.getInstanceUTC()); return convertToISODate(julianEasterDate); } /** * Returns the easter sunday within the gregorian chronology. * * @param year * a int. * @return gregorian easter sunday. */ public LocalDate getGregorianEasterSunday(int year) { int a, b, c, d, e, f, g, h, i, j, k, l; int x, month, day; a = year % 19; b = year / 100; c = year % 100; d = b / 4; e = b % 4; f = (b + 8) / 25; g = (b - f + 1) / 3; h = (19 * a + b - d - g + 15) % 30; i = c / 4; j = c % 4; k = (32 + 2 * e + 2 * i - h - j) % 7; l = (a + 11 * h + 22 * k) / 451; x = h + k - 7 * l + 114; month = x / 31; day = (x % 31) + 1; return create(year, (month == 3 ? DateTimeConstants.MARCH : DateTimeConstants.APRIL), day); } /** * Returns if this date is on a wekkend. * * @param date * a {@link org.joda.time.LocalDate} object. * @return is weekend */ public boolean isWeekend(final LocalDate date) { return date.getDayOfWeek() == DateTimeConstants.SATURDAY || date.getDayOfWeek() == DateTimeConstants.SUNDAY; } /** * Returns a set of gregorian dates within a gregorian year which equal the * islamic month and day. Because the islamic year is about 11 days shorter * than the gregorian there may be more than one occurrence of an islamic * date in an gregorian year. i.e.: In the gregorian year 2008 there were * two 1/1. They occurred on 1/10 and 12/29. * * @param gregorianYear * a int. * @param islamicMonth * a int. * @param islamicDay * a int. * @return List of gregorian dates for the islamic month/day. */ public Set<LocalDate> getIslamicHolidaysInGregorianYear(int gregorianYear, int islamicMonth, int islamicDay) { return getDatesFromChronologyWithinGregorianYear(islamicMonth, islamicDay, gregorianYear, IslamicChronology.getInstance()); } /** * Returns a set of gregorian dates within a gregorian year which equal the * ethiopian orthodox month and day. Because the ethiopian orthodox year * different from the gregorian there may be more than one occurrence of an * ethiopian orthodox date in an gregorian year. * * @param gregorianYear * a int. * @return List of gregorian dates for the ethiopian orthodox month/day. * @param eoMonth * a int. * @param eoDay * a int. */ public Set<LocalDate> getEthiopianOrthodoxHolidaysInGregorianYear(int gregorianYear, int eoMonth, int eoDay) { return getDatesFromChronologyWithinGregorianYear(eoMonth, eoDay, gregorianYear, CopticChronology.getInstance()); } /** * Searches for the occurrences of a month/day in one chronology within one * gregorian year. * * @param targetMonth * @param targetDay * @param gregorianYear * @param targetChrono * @return the list of gregorian dates. */ private Set<LocalDate> getDatesFromChronologyWithinGregorianYear(int targetMonth, int targetDay, int gregorianYear, Chronology targetChrono) { Set<LocalDate> holidays = new HashSet<LocalDate>(); LocalDate firstGregorianDate = new LocalDate(gregorianYear, DateTimeConstants.JANUARY, 1, ISOChronology.getInstance()); LocalDate lastGregorianDate = new LocalDate(gregorianYear, DateTimeConstants.DECEMBER, 31, ISOChronology.getInstance()); LocalDate firstTargetDate = new LocalDate(firstGregorianDate.toDateTimeAtStartOfDay().getMillis(), targetChrono); LocalDate lastTargetDate = new LocalDate(lastGregorianDate.toDateTimeAtStartOfDay().getMillis(), targetChrono); Interval interv = new Interval(firstTargetDate.toDateTimeAtStartOfDay(), lastTargetDate.plusDays(1).toDateTimeAtStartOfDay()); int targetYear = firstTargetDate.getYear(); for (; targetYear <= lastTargetDate.getYear();) { LocalDate d = new LocalDate(targetYear, targetMonth, targetDay, targetChrono); if (interv.contains(d.toDateTimeAtStartOfDay())) { holidays.add(convertToISODate(d)); } targetYear++; } return holidays; } /** * Converts the provided date into a date within the ISO chronology. If it * is already a ISO date it will return it. * * @param date * a {@link org.joda.time.LocalDate} object. * @return a {@link org.joda.time.LocalDate} object. */ public LocalDate convertToISODate(final LocalDate date) { if (!(date.getChronology() instanceof ISOChronology)) { return new LocalDate(date.toDateTimeAtStartOfDay().getMillis(), ISOChronology.getInstance()); } return date; } /** * Shows if the requested dat is contained in the Set of holidays. * * @param holidays * a {@link java.util.Set} object. * @param date * a {@link org.joda.time.LocalDate} object. * @return contains this date */ public boolean contains(final Set<Holiday> holidays, final LocalDate date) { for (Holiday h : holidays) { if (h.getDate().equals(date)) { return true; } } return false; } }