com.jjlharrison.jollyday.util.CalendarUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.jjlharrison.jollyday.util.CalendarUtil.java

Source

/**
 * 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;
    }

}