001/*
002 * Zmanim Java API
003 * Copyright (C) 2004-2025 Eliyahu Hershfeld
004 *
005 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
006 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
007 * any later version.
008 *
009 * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied
010 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
011 * details.
012 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
013 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA,
014 * or connect to: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
015 */
016package com.kosherjava.zmanim.util;
017
018import java.util.TimeZone;
019
020/**
021 * A class that represents a numeric time. Times that represent a time of day are stored as {@link java.util.Date}s in
022 * this API. The time class is used to represent numeric time such as the time in hours, minutes, seconds and
023 * milliseconds of a {@link com.kosherjava.zmanim.AstronomicalCalendar#getTemporalHour() temporal hour}.
024 * 
025 * @author © Eliyahu Hershfeld 2004 - 2025
026 */
027public class Time {
028        /** milliseconds in a second. */
029        private static final int SECOND_MILLIS = 1000;
030
031        /** milliseconds in a minute. */
032        private static final int MINUTE_MILLIS = SECOND_MILLIS * 60;
033
034        /** milliseconds in an hour. */
035        private static final int HOUR_MILLIS = MINUTE_MILLIS * 60;
036
037        /**
038         * The hour.
039         * @see #getHours()
040         */
041        private int hours;
042
043        /**
044         * The minutes.
045         * @see #getMinutes()
046         */
047        private int minutes;
048
049        /**
050         * The seconds.
051         * @see #getSeconds()
052         */
053        private int seconds;
054
055        /**
056         * The milliseconds.
057         * @see #getMilliseconds()
058         */
059        private int milliseconds;
060
061        /**
062         * Is the time negative
063         * @see #isNegative()
064         * @see #setIsNegative(boolean)
065         */
066        private boolean isNegative = false;
067
068        /**
069         * Constructor with parameters for the hours, minutes, seconds and milliseconds.
070         * 
071         * @param hours the hours to set
072         * @param minutes the minutes to set
073         * @param seconds the seconds to set
074         * @param milliseconds the milliseconds to set
075         */
076        public Time(int hours, int minutes, int seconds, int milliseconds) {
077                this.hours = hours;
078                this.minutes = minutes;
079                this.seconds = seconds;
080                this.milliseconds = milliseconds;
081        }
082
083        /**
084         * Constructor with a parameter for milliseconds. This constructor casts the milliseconds to an int and
085         * calls {@link #Time(int)}
086         * @param millis the milliseconds to set the object with.
087         */
088        public Time(double millis) {
089                this((int) millis);
090        }
091
092        /**
093         * A constructor that sets the time from milliseconds. The milliseconds are converted to hours, minutes,
094         * seconds and milliseconds. If the milliseconds are negative it will call {@link#setIsNegative(boolean)}.
095         * @param millis the milliseconds to set.
096         */
097        public Time(int millis) {
098                int adjustedMillis = millis;
099                if (adjustedMillis < 0) {
100                        this.isNegative = true;
101                        adjustedMillis = Math.abs(adjustedMillis);
102                }
103                this.hours = adjustedMillis / HOUR_MILLIS;
104                adjustedMillis = adjustedMillis - this.hours * HOUR_MILLIS;
105
106                this.minutes = adjustedMillis / MINUTE_MILLIS;
107                adjustedMillis = adjustedMillis - this.minutes * MINUTE_MILLIS;
108
109                this.seconds = adjustedMillis / SECOND_MILLIS;
110                adjustedMillis = adjustedMillis - this.seconds * SECOND_MILLIS;
111
112                this.milliseconds = adjustedMillis;
113        }
114
115        /**
116         * Does the time represent a negative time, such as using this to subtract time from another Time.
117         * @return if the time is negative.
118         */
119        public boolean isNegative() {
120                return this.isNegative;
121        }
122
123        /**
124         * Set this to represent a negative time.
125         * @param isNegative that the Time represents negative time
126         */
127        public void setIsNegative(boolean isNegative) {
128                this.isNegative = isNegative;
129        }
130
131        /**
132         * Get the hour.
133         * @return Returns the hour.
134         */
135        public int getHours() {
136                return this.hours;
137        }
138
139        /**
140         * Set the hour.
141         * @param hours
142         *            The hours to set.
143         */
144        public void setHours(int hours) {
145                this.hours = hours;
146        }
147
148        /**
149         * Get the minutes.
150         * @return Returns the minutes.
151         */
152        public int getMinutes() {
153                return this.minutes;
154        }
155
156        /**
157         * Set the minutes.
158         * @param minutes
159         *            The minutes to set.
160         */
161        public void setMinutes(int minutes) {
162                this.minutes = minutes;
163        }
164
165        /**
166         * Get the seconds.
167         * @return Returns the seconds.
168         */
169        public int getSeconds() {
170                return this.seconds;
171        }
172
173        /**
174         * Set the seconds.
175         * @param seconds
176         *            The seconds to set.
177         */
178        public void setSeconds(int seconds) {
179                this.seconds = seconds;
180        }
181
182        /**
183         * Get the milliseconds.
184         * @return Returns the milliseconds.
185         */
186        public int getMilliseconds() {
187                return this.milliseconds;
188        }
189
190        /**
191         * Set the milliseconds.
192         * @param milliseconds
193         *            The milliseconds to set.
194         */
195        public void setMilliseconds(int milliseconds) {
196                this.milliseconds = milliseconds;
197        }
198
199        /**
200         * Returns the time in milliseconds by converting hours, minutes and seconds into milliseconds.
201         * @return the time in milliseconds
202         */
203        public double getTime() {
204                return this.hours * HOUR_MILLIS + this.minutes * MINUTE_MILLIS + this.seconds * SECOND_MILLIS
205                                + this.milliseconds;
206        }
207
208        /**
209         * @see java.lang.Object#toString()
210         */
211        public String toString() {
212                return new ZmanimFormatter(TimeZone.getTimeZone("UTC")).format(this);
213        }
214}