Package org.pentaho.reporting.engine.classic.core.modules.gui.base.date

Source Code of org.pentaho.reporting.engine.classic.core.modules.gui.base.date.SerialDateUtilities

/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2000 - 2009 Pentaho Corporation, Object Refinery Limited and Contributors...  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.modules.gui.base.date;

import java.text.DateFormatSymbols;
import java.util.Calendar;

/**
* A utility class that provides a number of useful methods (some static).
* Many of these are used in the implementation of the day-count convention
* classes.  I recognise some limitations in this implementation:
* <p>
* [1] some of the methods assume that the default Calendar is a
* GregorianCalendar (used mostly to determine leap years) - so the code
* won&rsquo;t work if some other Calendar is the default.  I'm not sure how
* to handle this properly?
* <p>
* [2] a whole bunch of static methods isn't very object-oriented - but I couldn't think of a good
* way to extend the Date and Calendar classes to add the functions I required,
* so static methods are doing the job for now.
*
* @author David Gilbert
* @deprecated
*/
public class SerialDateUtilities {

    /** The default date format symbols. */
    private DateFormatSymbols dateFormatSymbols;

    /** Strings representing the weekdays. */
    private String[] weekdays;

    /** Strings representing the months. */
    private String[] months;

    /**
     * Creates a new utility class for the default locale.
     */
    public SerialDateUtilities() {
        this.dateFormatSymbols = new DateFormatSymbols();
        this.weekdays = this.dateFormatSymbols.getWeekdays();
        this.months = this.dateFormatSymbols.getMonths();
    }

    /**
     * Returns an array of strings representing the days-of-the-week.
     *
     * @return an array of strings representing the days-of-the-week.
     */
    public String[] getWeekdays() {
        return this.weekdays;
    }

    /**
     * Returns an array of strings representing the months.
     *
     * @return an array of strings representing the months.
     */
    public String[] getMonths() {
        return this.months;
    }

    /**
     * Returns the actual number of days between two dates.
     *
     * @param start  the start date.
     * @param end  the end date.
     *
     * @return the number of days between the start date and the end date.
     */
    public static int dayCountActual(final SerialDate start, final SerialDate end) {
        return end.compare(start);
    }

    /**
     * Returns the number of days between the specified start and end dates,
     * assuming that there are thirty days in every month (that is,
     * corresponding to the 30/360 day-count convention).
     * <P>
     * The method handles cases where the start date is before the end date (by
     * switching the dates and returning a negative result).
     *
     * @param start  the start date.
     * @param end  the end date.
     *
     * @return the number of days between the two dates, assuming the 30/360 day-count convention.
     */
    public static int dayCount30(final SerialDate start, final SerialDate end) {
        final int d1;
        final int m1;
        final int y1;
        final int d2;
        final int m2;
        final int y2;
        if (start.isBefore(end)) {  // check the order of the dates
            d1 = start.getDayOfMonth();
            m1 = start.getMonth();
            y1 = start.getYYYY();
            d2 = end.getDayOfMonth();
            m2 = end.getMonth();
            y2 = end.getYYYY();
            return 360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1);
        }
        else {
            return -dayCount30(end, start);
        }
    }

    /**
     * Returns the number of days between the specified start and end dates,
     * assuming that there are thirty days in every month, and applying the
     * ISDA adjustments (that is, corresponding to the 30/360 (ISDA) day-count
     * convention).
     * <P>
     * The method handles cases where the start date is before the end date (by
     * switching the dates around and returning a negative result).
     *
     * @param start  the start date.
     * @param end  the end date.
     *
     * @return The number of days between the two dates, assuming the 30/360
     *      (ISDA) day-count convention.
     */
    public static int dayCount30ISDA(final SerialDate start, final SerialDate end) {
        int d1;
        final int m1;
        final int y1;
        int d2;
        final int m2;
        final int y2;
        if (start.isBefore(end)) {
            d1 = start.getDayOfMonth();
            m1 = start.getMonth();
            y1 = start.getYYYY();
            if (d1 == 31) {  // first ISDA adjustment
                d1 = 30;
            }
            d2 = end.getDayOfMonth();
            m2 = end.getMonth();
            y2 = end.getYYYY();
            if ((d2 == 31) && (d1 == 30)) {  // second ISDA adjustment
                d2 = 30;
            }
            return 360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1);
        }
        else if (start.isAfter(end)) {
            return -dayCount30ISDA(end, start);
        }
        else {
            return 0;
        }
    }

    /**
     * Returns the number of days between the specified start and end dates,
     * assuming that there are thirty days in every month, and applying the PSA
     * adjustments (that is, corresponding to the 30/360 (PSA) day-count convention).
     * The method handles cases where the start date is before the end date (by
     * switching the dates around and returning a negative result).
     *
     * @param start  the start date.
     * @param end  the end date.
     *
     * @return The number of days between the two dates, assuming the 30/360
     *      (PSA) day-count convention.
     */
    public static int dayCount30PSA(final SerialDate start, final SerialDate end) {
        int d1;
        final int m1;
        final int y1;
        int d2;
        final int m2;
        final int y2;

        if (start.isOnOrBefore(end)) { // check the order of the dates
            d1 = start.getDayOfMonth();
            m1 = start.getMonth();
            y1 = start.getYYYY();

            if (SerialDateUtilities.isLastDayOfFebruary(start)) {
                d1 = 30;
            }
            if ((d1 == 31) || SerialDateUtilities.isLastDayOfFebruary(start)) {
                // first PSA adjustment
                d1 = 30;
            }
            d2 = end.getDayOfMonth();
            m2 = end.getMonth();
            y2 = end.getYYYY();
            if ((d2 == 31) && (d1 == 30)) {  // second PSA adjustment
                d2 = 30;
            }
            return 360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1);
        }
        else {
            return -dayCount30PSA(end, start);
        }
    }

    /**
     * Returns the number of days between the specified start and end dates,
     * assuming that there are thirty days in every month, and applying the
     * European adjustment (that is, corresponding to the 30E/360 day-count
     * convention).
     * <P>
     * The method handles cases where the start date is before the end date (by
     * switching the dates around and returning a negative result).
     *
     * @param start  the start date.
     * @param end  the end date.
     *
     * @return the number of days between the two dates, assuming the 30E/360
     *      day-count convention.
     */
    public static int dayCount30E(final SerialDate start, final SerialDate end) {
        int d1;
        final int m1;
        final int y1;
        int d2;
        final int m2;
        final int y2;
        if (start.isBefore(end)) {
            d1 = start.getDayOfMonth();
            m1 = start.getMonth();
            y1 = start.getYYYY();
            if (d1 == 31) {  // first European adjustment
                d1 = 30;
            }
            d2 = end.getDayOfMonth();
            m2 = end.getMonth();
            y2 = end.getYYYY();
            if (d2 == 31) {  // first European adjustment
                d2 = 30;
            }
            return 360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1);
        }
        else if (start.isAfter(end)) {
            return -dayCount30E(end, start);
        }
        else {
            return 0;
        }
    }

    /**
     * Returns true if the specified date is the last day in February (that is, the
     * 28th in non-leap years, and the 29th in leap years).
     *
     * @param d  the date to be tested.
     *
     * @return a boolean that indicates whether or not the specified date is
     *      the last day of February.
     */
    public static boolean isLastDayOfFebruary(final SerialDate d) {

        final int dom;
        if (d.getMonth() == MonthConstants.FEBRUARY) {
            dom = d.getDayOfMonth();
            if (SerialDate.isLeapYear(d.getYYYY())) {
                return (dom == 29);
            }
            else {
                return (dom == 28);
            }
        }
        else { // not even February
            return false;
        }

    }

    /**
     * Returns the number of times that February 29 falls within the specified
     * date range.  The result needs to correspond to the ACT/365 (Japanese)
     * day-count convention. The difficult cases are where the start or the
     * end date is Feb 29 (include or not?).  Need to find out how JGBs do this
     * (since this is where the ACT/365 (Japanese) convention comes from ...
     *
     * @param start  the start date.
     * @param end  the end date.
     *
     * @return the number of times that February 29 occurs within the date
     *      range.
     */
    public static int countFeb29s(final SerialDate start, final SerialDate end) {
        int count = 0;
        SerialDate feb29;
        final int y1;
        final int y2;
        int year;

        // check the order of the dates
        if (start.isBefore(end)) {

            y1 = start.getYYYY();
            y2 = end.getYYYY();
            for (year = y1; year == y2; year++) {
                if (SerialDate.isLeapYear(year)) {
                    feb29 = SerialDate.createInstance(29, MonthConstants.FEBRUARY, year);
                    if (feb29.isInRange(start, end, SerialDate.INCLUDE_SECOND)) {
                        count++;
                    }
                }
            }
            return count;
        }
        else {
            return countFeb29s(end, start);
        }
    }

}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.modules.gui.base.date.SerialDateUtilities

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.