001package biweekly.util;
002
003import java.util.Date;
004
005/*
006 Copyright (c) 2013-2015, Michael Angstadt
007 All rights reserved.
008
009 Redistribution and use in source and binary forms, with or without
010 modification, are permitted provided that the following conditions are met: 
011
012 1. Redistributions of source code must retain the above copyright notice, this
013 list of conditions and the following disclaimer. 
014 2. Redistributions in binary form must reproduce the above copyright notice,
015 this list of conditions and the following disclaimer in the documentation
016 and/or other materials provided with the distribution. 
017
018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
019 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
020 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
021 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
022 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
024 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
025 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028 */
029
030/**
031 * A period of time.
032 * @author Michael Angstadt
033 */
034public final class Period {
035        private final Date startDate;
036        private final Date endDate;
037        private final Duration duration;
038
039        /**
040         * Creates a new time period.
041         * @param startDate the start date
042         * @param endDate the end date
043         */
044        public Period(Date startDate, Date endDate) {
045                this.startDate = copy(startDate);
046                this.endDate = copy(endDate);
047                duration = null;
048        }
049
050        /**
051         * Creates a new time period.
052         * @param startDate the start date
053         * @param duration the length of time after the start date
054         */
055        public Period(Date startDate, Duration duration) {
056                this.startDate = copy(startDate);
057                this.duration = duration;
058                endDate = null;
059        }
060
061        /**
062         * Copies an existing time period.
063         * @param period the period to copy
064         */
065        public Period(Period period) {
066                this.startDate = period.startDate;
067                this.endDate = period.endDate;
068                this.duration = period.duration;
069        }
070
071        /**
072         * Gets the start date.
073         * @return the start date
074         */
075        public Date getStartDate() {
076                return copy(startDate);
077        }
078
079        /**
080         * Gets the end date. This will be null if a duration was defined.
081         * @return the end date or null if not set
082         */
083        public Date getEndDate() {
084                return copy(endDate);
085        }
086
087        /**
088         * Gets the length of time after the start date. This will be null if an end
089         * date was defined.
090         * @return the duration or null if not set
091         */
092        public Duration getDuration() {
093                return duration;
094        }
095
096        @Override
097        public int hashCode() {
098                final int prime = 31;
099                int result = 1;
100                result = prime * result + ((duration == null) ? 0 : duration.hashCode());
101                result = prime * result + ((endDate == null) ? 0 : endDate.hashCode());
102                result = prime * result + ((startDate == null) ? 0 : startDate.hashCode());
103                return result;
104        }
105
106        @Override
107        public boolean equals(Object obj) {
108                if (this == obj)
109                        return true;
110                if (obj == null)
111                        return false;
112                if (getClass() != obj.getClass())
113                        return false;
114                Period other = (Period) obj;
115                if (duration == null) {
116                        if (other.duration != null)
117                                return false;
118                } else if (!duration.equals(other.duration))
119                        return false;
120                if (endDate == null) {
121                        if (other.endDate != null)
122                                return false;
123                } else if (!endDate.equals(other.endDate))
124                        return false;
125                if (startDate == null) {
126                        if (other.startDate != null)
127                                return false;
128                } else if (!startDate.equals(other.startDate))
129                        return false;
130                return true;
131        }
132
133        private Date copy(Date date) {
134                return (date == null) ? null : new Date(date.getTime());
135        }
136}