All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.norconex.commons.lang.time.YearMonthDayInterval Maven / Gradle / Ivy

Go to download

Norconex Commons Lang is a Java library containing utility classes that complements the Java API and are not found in commonly available libraries (such as the great Apache Commons Lang, which it relies on).

There is a newer version: 2.0.2
Show newest version
/* Copyright 2010-2014 Norconex Inc.
 *
 * 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.norconex.commons.lang.time;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

/**
 * An immutable date interval where both the start and end are inclusive, unless
 * stated otherwise.  Start and end YearMonthDay instances cannot be
 * null and start date must be before or the same date as 
 * the end date.
 * @author Pascal Essiembre
 * @since 1.3.0
 */
public final class YearMonthDayInterval implements Serializable {

    private static final long serialVersionUID = -5607689446876900272L;

    private final YearMonthDay start;
    private final YearMonthDay end;
    
    
    public YearMonthDayInterval(YearMonthDay start, YearMonthDay end) {
        if (start == null || end == null) {
            throw new IllegalArgumentException(
                    "YearMonthday start and YearMonthday end cannot be null.");
        }
        if (start.isAfter(end)) {
            throw new IllegalArgumentException(
                    "YearMonthDay start cannot be after YearMonthDay end.");
        }
        this.start = start;
        this.end = end;
    }
    
    /**
     * Constructs a YearMonthDayInterval out of a string.  The recommended
     * string format is yyyy-MM-dd - yyyy-MM-dd, but any 
     * characters in between the start and end are accepted as long as there 
     * is a space after the start YearMontDay and before the end YearMonthDay.
     * @param interval the interval to parse
     */
    public YearMonthDayInterval(String interval) {
        String trimmed = StringUtils.trim(interval);
        String startStr = StringUtils.substringBefore(trimmed, " ");
        String endStr = StringUtils.substringAfterLast(trimmed, " ");
        if (StringUtils.isBlank(startStr) || StringUtils.isBlank(endStr)) {
            throw new IllegalArgumentException(
                    "String YearMonthDay interval cannot be null or empty.");
        }
        this.start = new YearMonthDay(startStr);
        this.end = new YearMonthDay(endStr);
    }
    public YearMonthDayInterval(Date start, Date end) {
        if (start == null || end == null) {
            throw new IllegalArgumentException(
                    "Date start and Date end cannot be null.");
        }
        this.start = new YearMonthDay(start);
        this.end = new YearMonthDay(end);
    }
    public YearMonthDayInterval(Calendar start, Calendar end) {
        if (start == null || end == null) {
            throw new IllegalArgumentException(
                    "Calendar start and Calendar end cannot be null.");
        }
        this.start = new YearMonthDay(start);
        this.end = new YearMonthDay(end);
    }    
    public YearMonthDay getStart() {
        return start;
    }
    public Date getStartDate() {
        return start.toDate();
    }
    public YearMonthDay getEnd() {
        return end;
    }
    public Date getEndDate() {
        return end.toDate();
    }
    /**
     * Gets the end date as midnight the day after to ensure all dates on the
     * same day as this YearMonthDay are smaller than this returned 
     * exclusive date.  Useful for date range comparisons where typically
     * the end date is exclusive.
     * @return midnight past the end date 
     */
    public Date getEndDateEndOfDay() {
        return end.toEndOfDayDate();
    }

    /**
     * Whether the YearMonthDay falls between this interval 
     * (inclusive endpoints).
     * @param ymd the YearMonthDay
     * @return true if YearMonthDay is included in this interval
     */
    public boolean contains(YearMonthDay ymd) {
        if (start.isAfter(ymd)) {
            return false;
        }
        if (end.isBefore(ymd)) {
            return false;
        }
        return true;
    }
    /**
     * Whether the date falls between this interval 
     * (inclusive endpoints).
     * @param date a date
     * @return true if the date is included in this interval
     */
    public boolean contains(Date date) {
        Date startDate = start.toDate();
        Date endDate = end.toDate();
        if (startDate.after(date)) {
            return false;
        }
        if (endDate.before(date)) {
            return false;
        }
        return true;
    }

    /**
     * Gets the number of years between start and end dates, rounded down.
     * @return number of years
     */
    public int getYears() {
        int years = end.getYear() - start.getYear();
        if (end.getMonth() < start.getMonth()) {
            return years - 1;
        }
        if (end.getMonth() == start.getMonth()
                && end.getDay() < start.getDay()) {
            return years - 1;
        }
        return years;
    }
    /**
     * Gets the number of months between start and end dates, rounded down.
     * @return number of months
     */
    public int getMonths() {
        int months = 0;
        Calendar cal = start.toCalendar();
        Calendar endCal = end.toCalendar();
        cal.add(Calendar.MONTH, 1);
        while (!cal.after(endCal)) {
            months++;
            cal.add(Calendar.MONTH, 1);
        }
        return months;
    }
    /**
     * Gets the number of days between start and end dates, rounded down.
     * @return number of days
     */
    public int getDays() {
        return (int) ((end.toMillis() - start.toMillis()) 
                / DateUtils.MILLIS_PER_DAY);
    }
    
    /**
     * Gets the interval as a string of this format:
     *  yyyy-MM-dd - yyyy-MM-dd;
     *  @return interval as string
     */
    @Override
    public String toString() {
        return start + " - " + end;
    }
    
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy