package org.marketcetera.photon; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import org.marketcetera.util.except.ExceptUtils; import org.marketcetera.util.misc.ClassVersion; /* $License$ */ /** * Utility class that represents a particular time of day (hour, minute, * second). * * @author <a href="mailto:will@marketcetera.com">Will Horn</a> * @version $Id: TimeOfDay.java 16154 2012-07-14 16:34:05Z colin $ * @since 1.0.0 */ @ClassVersion("$Id: TimeOfDay.java 16154 2012-07-14 16:34:05Z colin $") public class TimeOfDay { /** * Create a new object from provided parameters. * * @param hour * the hour of the day * @param minute * the minute of the hour * @param second * the second of the minute * @param timeZone * the time zone assumed by the other parameters * @return the new TimeOfDay object */ public static TimeOfDay create(int hour, int minute, int second, TimeZone timeZone) { Calendar in = getCalendar(hour, minute, second, timeZone); Calendar out = Calendar.getInstance(UTC); out.setTime(in.getTime()); return create(out); } /** * Create a new object from a string. The string must be formatted according * to <code>h:mm:ss a z</code> as described in {@link SimpleDateFormat}. If * the format is invalid, <code>null</code> will be returned. * * @param string * the string to parse * @return the new TimeOfDay object, or null if the string could not be * parsed */ public static TimeOfDay create(String string) { try { Date date = sFormat.parse(string); Calendar calendar = Calendar.getInstance(UTC); calendar.setTime(date); return create(calendar); } catch (ParseException e) { ExceptUtils.swallow(e); return null; } } private static final int ONE_DAY = 86400000; // 24*60*60*1000 private static final TimeZone UTC = TimeZone.getTimeZone("UTC"); //$NON-NLS-1$ private static final DateFormat sFormat; static { sFormat = new SimpleDateFormat("h:mm:ss a z"); //$NON-NLS-1$ sFormat.setTimeZone(UTC); } private static TimeOfDay create(Calendar calendar) { return new TimeOfDay(calendar.get(Calendar.HOUR_OF_DAY), calendar .get(Calendar.MINUTE), calendar.get(Calendar.SECOND)); } private static Calendar getCalendar(int hour, int minute, int second, TimeZone timeZone) { Calendar calendar = Calendar.getInstance(timeZone); calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minute); calendar.set(Calendar.SECOND, second); return calendar; } private int mHour; private int mMinute; private int mSecond; private TimeOfDay(int hour, int minute, int second) { mHour = hour; mMinute = minute; mSecond = second; } /** * Returns the hour in the provided time zone. This returns the hour from 0 to 23 (military * time). * * @return the hour in the provided time zone */ public int getHour(TimeZone timeZone) { return getCalendar(timeZone).get(Calendar.HOUR_OF_DAY); } /** * Returns the minute in the provided time zone. * * @return the minute in the provided time zone */ public int getMinute(TimeZone timeZone) { return getCalendar(timeZone).get(Calendar.MINUTE); } /** * Returns the second in the provided time zone. * * @return the second in the provided time zone */ public int getSecond(TimeZone timeZone) { return getCalendar(timeZone).get(Calendar.SECOND); } /** * This object formatted as a string according to <code>h:mm:ss a z</code> * as described by {@link SimpleDateFormat}. * * It is guaranteed that this object can be recreated from the returned * string using {@link #create(String)}. * * @return the string representation of this object */ public String toFormattedString() { Calendar calendar = getCalendar(); return sFormat.format(calendar.getTime()); } /** * Returns the last occurrence of this time of day, that is, the latest * {@link Date} that has the same time of day as this object and is also * earlier than the current time as determined by the system time. * * It is guaranteed that the {@link Date} object returned will be less than * or equal to any system time computed after this method returns. * * @return the last occurrence */ public Date getLastOccurrence() { Calendar now = Calendar.getInstance(UTC); Calendar calendar = getCalendar(); calendar.set(Calendar.YEAR, now.get(Calendar.YEAR)); calendar.set(Calendar.DAY_OF_YEAR, now.get(Calendar.DAY_OF_YEAR)); if (calendar.after(now)) { return new Date(calendar.getTime().getTime() - ONE_DAY); } return calendar.getTime(); } private Calendar getCalendar() { return getCalendar(mHour, mMinute, mSecond, UTC); } private Calendar getCalendar(TimeZone timeZone) { Calendar utc = getCalendar(); Calendar out = Calendar.getInstance(timeZone); out.setTime(utc.getTime()); return out; } }