001package biweekly.util;
002
003import java.util.Calendar;
004import java.util.Date;
005
006/*
007 Copyright (c) 2013-2015, Michael Angstadt
008 All rights reserved.
009
010 Redistribution and use in source and binary forms, with or without
011 modification, are permitted provided that the following conditions are met: 
012
013 1. Redistributions of source code must retain the above copyright notice, this
014 list of conditions and the following disclaimer. 
015 2. Redistributions in binary form must reproduce the above copyright notice,
016 this list of conditions and the following disclaimer in the documentation
017 and/or other materials provided with the distribution. 
018
019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030
031/**
032 * Represents a date-time value. Includes extra information that is used within
033 * this library.
034 * @author Michael Angstadt
035 */
036public class ICalDate extends Date {
037        private static final long serialVersionUID = -8172624513821588097L;
038
039        private final DateTimeComponents rawComponents;
040        private final boolean hasTime;
041
042        /**
043         * Creates a new date-time value set to the current date and time.
044         */
045        public ICalDate() {
046                this(true);
047        }
048
049        /**
050         * Creates a new date-time value set to the current date or time.
051         * @param hasTime true to include the time component, false not to
052         */
053        public ICalDate(boolean hasTime) {
054                this(new Date(), null, hasTime);
055        }
056
057        /**
058         * Creates a new date-time value (includes the time component).
059         * @param date the date-time value
060         */
061        public ICalDate(Date date) {
062                this(date, true);
063        }
064
065        /**
066         * Creates a new date-time value.
067         * @param date the date-time value
068         * @param hasTime true to include the time component, false not to
069         */
070        public ICalDate(Date date, boolean hasTime) {
071                this(date, null, hasTime);
072        }
073
074        /**
075         * Creates a new date-time value.
076         * @param date the date-time value components
077         * @param hasTime true to include the time component, false not to
078         */
079        public ICalDate(DateTimeComponents date, boolean hasTime) {
080                this(date.toDate(), date, hasTime);
081        }
082
083        /**
084         * Copies another iCal date-time value.
085         * @param date the date-time value
086         */
087        public ICalDate(ICalDate date) {
088                this(date, (date.rawComponents == null) ? null : new DateTimeComponents(date.rawComponents), date.hasTime);
089        }
090
091        /**
092         * Creates a new date-time value.
093         * @param date the date-time value
094         * @param rawComponents the raw date-time value as parsed from the input
095         * stream
096         * @param hasTime true if the date-time value has a time component, false if
097         * not
098         */
099        public ICalDate(Date date, DateTimeComponents rawComponents, boolean hasTime) {
100                if (!hasTime) {
101                        Calendar c = Calendar.getInstance();
102                        c.setTime(date);
103                        c.set(Calendar.HOUR_OF_DAY, 0);
104                        c.set(Calendar.MINUTE, 0);
105                        c.set(Calendar.SECOND, 0);
106                        c.set(Calendar.MILLISECOND, 0);
107                        date = c.getTime();
108                }
109
110                setTime(date.getTime());
111                this.rawComponents = rawComponents;
112                this.hasTime = hasTime;
113        }
114
115        /**
116         * Gets the raw date-time components of the value as read from the input
117         * stream.
118         * @return the raw date-time components or null if not set
119         */
120        public DateTimeComponents getRawComponents() {
121                return rawComponents;
122        }
123
124        /**
125         * Gets whether the value contains a time component.
126         * @return true if the value contains a time component, false if it's
127         * strictly a date.
128         */
129        public boolean hasTime() {
130                return hasTime;
131        }
132
133        @Override
134        public boolean equals(Object obj) {
135                if (obj instanceof ICalDate) {
136                        ICalDate other = (ICalDate) obj;
137                        if (hasTime != other.hasTime) return false;
138                }
139                return super.equals(obj);
140        }
141}