1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package java.sql;
19 
20 import java.util.Date;
21 
22 /**
23  * Java representation of an SQL {@code TIME} value. Provides utilities to
24  * format and parse the time's representation as a String in JDBC escape format.
25  */
26 public class Time extends Date {
27 
28     private static final long serialVersionUID = 8397324403548013681L;
29 
30     /**
31      * Constructs a {@code Time} object using the supplied values for <i>Hour</i>,
32      * <i>Minute</i> and <i>Second</i>. The <i>Year</i>, <i>Month</i> and
33      * <i>Day</i> elements of the {@code Time} object are set to the date
34      * of the Epoch (January 1, 1970).
35      * <p>
36      * Any attempt to access the <i>Year</i>, <i>Month</i> or <i>Day</i>
37      * elements of a {@code Time} object will result in an {@code
38      * IllegalArgumentException}.
39      * <p>
40      * The result is undefined if any argument is out of bounds.
41      *
42      * @deprecated Use the constructor {@link #Time(long)} instead.
43      * @param theHour
44      *            a value in the range {@code [0,23]}.
45      * @param theMinute
46      *            a value in the range {@code [0,59]}.
47      * @param theSecond
48      *            a value in the range {@code [0,59]}.
49      */
50     @SuppressWarnings("deprecation")
51     @Deprecated
Time(int theHour, int theMinute, int theSecond)52     public Time(int theHour, int theMinute, int theSecond) {
53         super(70, 0, 1, theHour, theMinute, theSecond);
54     }
55 
56     /**
57      * Constructs a {@code Time} object using a supplied time specified in
58      * milliseconds.
59      *
60      * @param theTime
61      *            a {@code Time} specified in milliseconds since the
62      *            <i>Epoch</i> (January 1st 1970, 00:00:00.000).
63      */
Time(long theTime)64     public Time(long theTime) {
65         super(theTime);
66     }
67 
68     /**
69      * @deprecated This method is deprecated and must not be used. An SQL
70      *             {@code Time} object does not have a date component.
71      * @return does not return anything.
72      * @throws IllegalArgumentException
73      *             if this method is called.
74      */
75     @SuppressWarnings("deprecation")
76     @Deprecated
77     @Override
getDate()78     public int getDate() {
79         throw new IllegalArgumentException("unimplemented");
80     }
81 
82     /**
83      * @deprecated This method is deprecated and must not be used. An SQL
84      *             {@code Time} object does not have a day component.
85      * @return does not return anything.
86      * @throws IllegalArgumentException
87      *             if this method is called.
88      */
89     @SuppressWarnings("deprecation")
90     @Deprecated
91     @Override
getDay()92     public int getDay() {
93         throw new IllegalArgumentException("unimplemented");
94     }
95 
96     /**
97      * @deprecated This method is deprecated and must not be used. An SQL
98      *             {@code Time} object does not have a month component.
99      * @return does not return anything.
100      * @throws IllegalArgumentException
101      *             if this method is called.
102      */
103     @SuppressWarnings("deprecation")
104     @Deprecated
105     @Override
getMonth()106     public int getMonth() {
107         throw new IllegalArgumentException("unimplemented");
108     }
109 
110     /**
111      * @deprecated This method is deprecated and must not be used. An SQL
112      *             {@code Time} object does not have a year component.
113      * @return does not return anything.
114      * @throws IllegalArgumentException
115      *             if this method is called.
116      */
117     @SuppressWarnings("deprecation")
118     @Deprecated
119     @Override
getYear()120     public int getYear() {
121         throw new IllegalArgumentException("unimplemented");
122     }
123 
124     /**
125      * @deprecated This method is deprecated and must not be used. An SQL
126      *             {@code Time} object does not have a date component.
127      * @throws IllegalArgumentException
128      *             if this method is called.
129      */
130     @SuppressWarnings("deprecation")
131     @Deprecated
132     @Override
setDate(int i)133     public void setDate(int i) {
134         throw new IllegalArgumentException("unimplemented");
135     }
136 
137     /**
138      * @deprecated This method is deprecated and must not be used. An SQL
139      *             {@code Time} object does not have a month component.
140      * @throws IllegalArgumentException
141      *             if this method is called.
142      */
143     @SuppressWarnings("deprecation")
144     @Deprecated
145     @Override
setMonth(int i)146     public void setMonth(int i) {
147         throw new IllegalArgumentException("unimplemented");
148     }
149 
150     /**
151      * @deprecated This method is deprecated and must not be used. An SQL
152      *             {@code Time} object does not have a year component.
153      * @throws IllegalArgumentException
154      *             if this method is called.
155      */
156     @SuppressWarnings("deprecation")
157     @Deprecated
158     @Override
setYear(int i)159     public void setYear(int i) {
160         throw new IllegalArgumentException("unimplemented");
161     }
162 
163     /**
164      * Sets the time for this {@code Time} object to the supplied milliseconds
165      * value.
166      *
167      * @param time
168      *            A time value expressed as milliseconds since the <i>Epoch</i>.
169      *            Negative values are milliseconds before the Epoch. The Epoch
170      *            is January 1 1970, 00:00:00.000.
171      */
172     @Override
setTime(long time)173     public void setTime(long time) {
174         super.setTime(time);
175     }
176 
177     /**
178      * Formats the {@code Time} as a String in JDBC escape format: {@code
179      * hh:mm:ss}.
180      *
181      * @return A String representing the {@code Time} value in JDBC escape
182      *         format: {@code HH:mm:ss}
183      */
184     @Override
toString()185     public String toString() {
186         StringBuilder sb = new StringBuilder(8);
187 
188         format(getHours(), 2, sb);
189         sb.append(':');
190         format(getMinutes(), 2, sb);
191         sb.append(':');
192         format(getSeconds(), 2, sb);
193 
194         return sb.toString();
195     }
196 
197     private static final String PADDING = "00";
198 
199     /*
200     * Private method to format the time
201     */
format(int date, int digits, StringBuilder sb)202     private void format(int date, int digits, StringBuilder sb) {
203         String str = String.valueOf(date);
204         if (digits - str.length() > 0) {
205             sb.append(PADDING.substring(0, digits - str.length()));
206         }
207         sb.append(str);
208     }
209 
210     /**
211      * Creates a {@code Time} object from a string holding a time represented in
212      * JDBC escape format: {@code hh:mm:ss}.
213      * <p>
214      * An exception occurs if the input string does not comply with this format.
215      *
216      * @param timeString
217      *            A String representing the time value in JDBC escape format:
218      *            {@code hh:mm:ss}.
219      * @return The {@code Time} object set to a time corresponding to the given
220      *         time.
221      * @throws IllegalArgumentException
222      *             if the supplied time string is not in JDBC escape format.
223      */
valueOf(String timeString)224     public static Time valueOf(String timeString) {
225         if (timeString == null) {
226             throw new IllegalArgumentException("timeString == null");
227         }
228         int firstIndex = timeString.indexOf(':');
229         int secondIndex = timeString.indexOf(':', firstIndex + 1);
230         // secondIndex == -1 means none or only one separator '-' has been
231         // found.
232         // The string is separated into three parts by two separator characters,
233         // if the first or the third part is null string, we should throw
234         // IllegalArgumentException to follow RI
235         if (secondIndex == -1 || firstIndex == 0
236                 || secondIndex + 1 == timeString.length()) {
237             throw new IllegalArgumentException();
238         }
239         // parse each part of the string
240         int hour = Integer.parseInt(timeString.substring(0, firstIndex));
241         int minute = Integer.parseInt(timeString.substring(firstIndex + 1,
242                 secondIndex));
243         int second = Integer.parseInt(timeString.substring(secondIndex + 1,
244                 timeString.length()));
245         return new Time(hour, minute, second);
246     }
247 }
248