001: /*
002: * $Id: Time.java 460526 2006-05-05 15:34:00Z jonl $ $Revision: 460526 $ $Date:
003: * 2006-01-04 01:28:14 -0800 (Wed, 04 Jan 2006) $
004: *
005: * ==============================================================================
006: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007: * use this file except in compliance with the License. You may obtain a copy of
008: * the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015: * License for the specific language governing permissions and limitations under
016: * the License.
017: */
018: package wicket.util.time;
019:
020: import java.text.ParseException;
021: import java.text.SimpleDateFormat;
022: import java.util.Calendar;
023: import java.util.Date;
024:
025: /**
026: * An immutable Time class that represents a specific point in time. The
027: * underlying representation is a long value which holds a number of
028: * milliseconds since January 1, 1970, 0:00 GMT. To represent a time duration,
029: * such as "6 seconds", use the Duration class. To represent a time period with
030: * a start and end time, use the TimeFrame class. To represent a time of day,
031: * use the TimeOfDay class.
032: *
033: * @author Jonathan Locke
034: */
035: public final class Time extends AbstractTime {
036: private static final long serialVersionUID = 1L;
037:
038: /** The beginning of UNIX time: January 1, 1970, 0:00 GMT. */
039: public static final Time START_OF_UNIX_TIME = milliseconds(0);
040:
041: /** Parser in 'yyyy.MM.dd' format. */
042: private static final SimpleDateFormat dateFormat = new SimpleDateFormat(
043: "yyyy.MM.dd");
044:
045: /** Parser in 'yyyy.MM.dd-h.mma' format. */
046: private static final SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
047: "yyyy.MM.dd-h.mma");
048:
049: /**
050: * Gets a Time instance based on the given miliseconds.
051: *
052: * @param time
053: * The time in milliseconds since START_OF_UNIX_TIME
054: * @return The given time
055: */
056: public static Time milliseconds(final long time) {
057: return new Time(time);
058: }
059:
060: /**
061: * Gets a Time instance based on the current time.
062: *
063: * @return The current time
064: */
065: public static Time now() {
066: return new Time(System.currentTimeMillis());
067: }
068:
069: /**
070: * Gets time by parsing 'yyyy.MM.dd' format.
071: *
072: * @param calendar
073: * The calendar to use when parsing date string
074: * @param string
075: * The string
076: * @return The time
077: * @throws ParseException
078: */
079: public static Time parseDate(final Calendar calendar,
080: final String string) throws ParseException {
081: synchronized (dateFormat) {
082: synchronized (calendar) {
083: dateFormat.setCalendar(calendar);
084:
085: return valueOf(dateFormat.parse(string));
086: }
087: }
088: }
089:
090: /**
091: * Gets time by parsing 'yyyy.MM.dd' format using a localtime calendar.
092: *
093: * @param string
094: * The string
095: * @return The time
096: * @throws ParseException
097: */
098: public static Time parseDate(final String string)
099: throws ParseException {
100: return parseDate(localtime, string);
101: }
102:
103: /**
104: * Gets time by parsing yyyy.MM.dd-h.mma format.
105: *
106: * @param calendar
107: * The calendar to use when parsing the string
108: * @param string
109: * The string
110: * @return An immutable UNIX time value
111: * @throws ParseException
112: */
113: public static Time valueOf(final Calendar calendar,
114: final String string) throws ParseException {
115: synchronized (dateTimeFormat) {
116: synchronized (calendar) {
117: dateTimeFormat.setCalendar(calendar);
118:
119: return valueOf(dateTimeFormat.parse(string));
120: }
121: }
122: }
123:
124: /**
125: * Gets a Time instance based on the given calendar and {@link TimeOfDay}
126: * objects.
127: *
128: * @param calendar
129: * The calendar to use
130: * @param timeOfDay
131: * The time of day
132: * @return A time value for the time of day today
133: */
134: public static Time valueOf(final Calendar calendar,
135: final TimeOfDay timeOfDay) {
136: synchronized (calendar) {
137: // Set time to midnight today
138: calendar.setTimeInMillis(System.currentTimeMillis());
139: calendar.set(Calendar.HOUR, 0);
140: calendar.set(Calendar.MINUTE, 0);
141: calendar.set(Calendar.SECOND, 0);
142:
143: // Add time of day milliseconds to midnight
144: return valueOf(calendar.getTimeInMillis()
145: + timeOfDay.getMilliseconds());
146: }
147: }
148:
149: /**
150: * Gets a Time instance based on the given date object.
151: *
152: * @param date
153: * A java.util.Date object
154: * @return A corresponding immutable Time object
155: */
156: public static Time valueOf(final Date date) {
157: return new Time(date.getTime());
158: }
159:
160: /**
161: * Gets a Time instance based on the given miliseconds.
162: *
163: * @param time
164: * The time in milliseconds since START_OF_UNIX_TIME
165: * @return A corresponding immutable Time object
166: */
167: public static Time valueOf(final long time) {
168: return new Time(time);
169: }
170:
171: /**
172: * Gets time by parsing yyyy.MM.dd-h.mma format.
173: *
174: * @param string
175: * The string
176: * @return The time
177: * @throws ParseException
178: */
179: public static Time valueOf(final String string)
180: throws ParseException {
181: return valueOf(localtime, string);
182: }
183:
184: /**
185: * Gets time by parsing 'pattern' format.
186: *
187: * @param string
188: * input
189: * @param pattern
190: * pattern to use
191: * @return Time instance that resulted from parsing the given string
192: * @throws ParseException
193: */
194: public static Time valueOf(final String string, final String pattern)
195: throws ParseException {
196: final SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
197: pattern);
198: dateTimeFormat.setCalendar(localtime);
199: return valueOf(dateTimeFormat.parse(string));
200: }
201:
202: /**
203: * Gets a Time instance based on the given {@link TimeOfDay}object.
204: *
205: * @param timeOfDay
206: * The time of day in localtime
207: * @return A time value for the time of day today
208: */
209: public static Time valueOf(final TimeOfDay timeOfDay) {
210: return valueOf(localtime, timeOfDay);
211: }
212:
213: /**
214: * Private constructor forces use of static factory methods.
215: *
216: * @param time
217: * The time in milliseconds since START_OF_UNIX_TIME
218: */
219: private Time(final long time) {
220: super (time);
221: }
222:
223: /**
224: * Adds the given duration to this time object, moving the time into the
225: * future.
226: *
227: * @param duration
228: * The duration to add
229: * @return This time + duration
230: */
231: public Time add(final Duration duration) {
232: return milliseconds(getMilliseconds()
233: + duration.getMilliseconds());
234: }
235:
236: /**
237: * @return Amount of time that has elapsed since this time
238: * @throws IllegalStateException Thrown if this time is in the future
239: */
240: public Duration elapsedSince() {
241: final Time now = now();
242: if (this .greaterThan(now)) {
243: throw new IllegalStateException(
244: "This time is in the future");
245: }
246: return now.subtract(this );
247: }
248:
249: /**
250: * Gets the duration from now to this time value. If this time value is in
251: * the past, then the Duration returned will be negative. Otherwise, it will
252: * be the number of milliseconds from now to this Time.
253: *
254: * @return The duration from now to this time value
255: */
256: public Duration fromNow() {
257: return subtract(now());
258: }
259:
260: /**
261: * Gets the value of a field from the given calendar.
262: *
263: * @param calendar
264: * The calendar to use
265: * @param field
266: * The calendar field to get
267: * @return The field's value for this point in time on the given calendar
268: */
269: public int get(final Calendar calendar, final int field) {
270: synchronized (calendar) {
271: calendar.setTimeInMillis(getMilliseconds());
272:
273: return calendar.get(field);
274: }
275: }
276:
277: /**
278: * Gets the value of a field.
279: *
280: * @param field
281: * The calendar field to get
282: * @return The field's value (in localtime)
283: */
284: public int get(final int field) {
285: return get(localtime, field);
286: }
287:
288: /**
289: * Gets the day of month field of the current calendar.
290: *
291: * @return the field value
292: */
293: public int getDayOfMonth() {
294: return getDayOfMonth(localtime);
295: }
296:
297: /**
298: * Gets the day of month field of the given calendar.
299: *
300: * @param calendar
301: * the calendar to get the field value from
302: * @return the field value
303: */
304: public int getDayOfMonth(final Calendar calendar) {
305: return get(calendar, Calendar.DAY_OF_MONTH);
306: }
307:
308: /**
309: * Gets the hour field of the current calendar.
310: *
311: * @return the field value
312: */
313: public int getHour() {
314: return getHour(localtime);
315: }
316:
317: /**
318: * Gets the hour field of the given calendar.
319: *
320: * @param calendar
321: * the calendar to get the field value from
322: * @return the field value
323: */
324: public int getHour(final Calendar calendar) {
325: return get(calendar, Calendar.HOUR);
326: }
327:
328: /**
329: * Gets the minute field of the current calendar.
330: *
331: * @return the field value
332: */
333: public int getMinute() {
334: return getMinute(localtime);
335: }
336:
337: /**
338: * Gets the minute field of the given calendar.
339: *
340: * @param calendar
341: * the calendar to get the field value from
342: * @return the field value
343: */
344: public int getMinute(final Calendar calendar) {
345: return get(calendar, Calendar.MINUTE);
346: }
347:
348: /**
349: * Gets the month field of the current calendar.
350: *
351: * @return the field value
352: */
353: public int getMonth() {
354: return getMonth(localtime);
355: }
356:
357: /**
358: * Gets the month field of the given calendar.
359: *
360: * @param calendar
361: * the calendar to get the field value from
362: * @return the field value
363: */
364: public int getMonth(final Calendar calendar) {
365: return get(calendar, Calendar.MONTH);
366: }
367:
368: /**
369: * Gets the second field of the current calendar.
370: *
371: * @return the field value
372: */
373: public int getSecond() {
374: return getSecond(localtime);
375: }
376:
377: /**
378: * Gets the second field of the given calendar.
379: *
380: * @param calendar
381: * the calendar to get the field value from
382: * @return the field value
383: */
384: public int getSecond(final Calendar calendar) {
385: return get(calendar, Calendar.SECOND);
386: }
387:
388: /**
389: * Gets the year field of the current calendar.
390: *
391: * @return the field value
392: */
393: public int getYear() {
394: return getYear(localtime);
395: }
396:
397: /**
398: * Gets the year field of the given calendar.
399: *
400: * @param calendar
401: * the calendar to get the field value from
402: * @return the field value
403: */
404: public int getYear(final Calendar calendar) {
405: return get(calendar, Calendar.YEAR);
406: }
407:
408: /**
409: * Adds the given duration to this time object, moving the time into the
410: * future.
411: *
412: * @param duration
413: * The duration to add
414: * @return This time - duration
415: */
416: public Time subtract(final Duration duration) {
417: return milliseconds(getMilliseconds()
418: - duration.getMilliseconds());
419: }
420:
421: /**
422: * Subtract time from this and returns the difference as a duration object.
423: *
424: * @param that
425: * The time to subtract
426: * @return The duration between this and that time
427: */
428: public Duration subtract(final Time that) {
429: return Duration.milliseconds(this .getMilliseconds()
430: - that.getMilliseconds());
431: }
432:
433: /**
434: * Gets a Date object for this time object. A new Date object is always
435: * returned rather than attempting to cache a date since Date is mutable.
436: *
437: * @return This immutable time object as a mutable java.util.Date object
438: */
439: public Date toDate() {
440: return new Date(getMilliseconds());
441: }
442:
443: /**
444: * Converts this time to a date string using the date formatter
445: * 'yyyy.MM.dd'.
446: *
447: * @return The date string
448: */
449: public String toDateString() {
450: return toDateString(localtime);
451: }
452:
453: /**
454: * Converts this time to a date string using the formatter 'yyyy.MM.dd'.
455: *
456: * @param calendar
457: * The calendar to use in the conversion
458: * @return The date string
459: */
460: public String toDateString(final Calendar calendar) {
461: synchronized (dateFormat) {
462: synchronized (calendar) {
463: dateFormat.setCalendar(calendar);
464:
465: return dateFormat.format(new Date(getMilliseconds()))
466: .toLowerCase();
467: }
468: }
469: }
470:
471: /**
472: * Converts this time to a string suitable for use in a filesystem name.
473: *
474: * @return This time as a formatted string
475: */
476: public String toString() {
477: return toDateString() + "-" + toTimeString();
478: }
479:
480: /**
481: * Converts this time to a string using the given calendar and format.
482: *
483: * @param calendar
484: * the calendar to use
485: * @param format
486: * the format to use
487: * @return This time as a formatted string
488: */
489: public String toString(final Calendar calendar, final String format) {
490: final SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
491: format);
492: dateTimeFormat.setCalendar(calendar == null ? localtime
493: : calendar);
494: return dateTimeFormat.format(new Date(getMilliseconds()));
495: }
496:
497: /**
498: * Converts this time to a string using the given format.
499: *
500: * @param format
501: * the format to use
502: * @return This time as a formatted string
503: */
504: public String toString(final String format) {
505: return toString(null, format);
506: }
507: }
|