001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.util.time; 018 019import java.text.ParseException; 020import java.util.Calendar; 021import org.apache.wicket.util.lang.EnumeratedType; 022 023 024/** 025 * An immutable time of day value represented as milliseconds since the most recent midnight. 026 * <p> 027 * Values can be constructed using various factory methods: 028 * <ul> 029 * <li><code>valueOf(long)</code> where <code>long</code> is milliseconds since midnight 030 * <li><code>valueOf(String)</code> where the <code>String</code> is in 'h.mma' format 031 * <li><code>valueOf(Calendar, String)</code> where the <code>String</code> is in 'h.mma' format 032 * <li><code>valueOf(Duration)</code> where <code>Duration</code> is time since midnight 033 * <li><code>valueOf(Time)</code> where <code>Time</code> is some point in time today 034 * <li><code>valueOf(Calendar, Time)</code> where <code>Time</code> is some point in time today 035 * <li><code>militaryTime(int hour, int minute, int second)</code> for 24-hour time 036 * <li><code>time(int hour, int minute, Meridian)</code> where <code>Meridian</code> is AM or PM 037 * <li><code>time(int hour, int minute, int second, Meridian)</code> where <code>Meridian</code> is 038 * AM or PM 039 * <li><code>now()</code> to construct the current time of day 040 * <li><code>now(Calendar)</code> to construct the current time of day using a given 041 * <code>Calendar</code> 042 * </ul> 043 * <p> 044 * If an attempt is made to construct an illegal time of day value (one that is greater than 24 045 * hours worth of milliseconds), an <code>IllegalArgumentException</code> will be thrown. 046 * <p> 047 * Military hours, minutes and seconds of the time of day can be retrieved by calling the 048 * <code>hour</code>, <code>minute</code>, and <code>second</code> methods. 049 * <p> 050 * The next occurrence of a given <code>TimeOfDay</code> can be retrieved by calling 051 * <code>next()</code> or <code>next(Calendar)</code>. 052 * 053 * @author Jonathan Locke 054 * @since 1.2.6 055 * 056 * @deprecated Since Wicket 9 this class is obsolete and no more used. It will be removed in Wicket 10 057 */ 058@Deprecated 059public final class TimeOfDay extends AbstractTime 060{ 061 private static final long serialVersionUID = 1L; 062 063 /** Constant for AM time. */ 064 public static final Meridian AM = new Meridian("AM"); 065 066 /** Constant for midnight. */ 067 public static final TimeOfDay MIDNIGHT = time(12, 0, AM); 068 069 /** Constant for PM time. */ 070 public static final Meridian PM = new Meridian("PM"); 071 072 /** Constant for noon. */ 073 public static final TimeOfDay NOON = time(12, 0, PM); 074 075 /** Typesafe AM/PM enumeration. */ 076 public static final class Meridian extends EnumeratedType 077 { 078 private static final long serialVersionUID = 1L; 079 080 /** 081 * Constructor. 082 * 083 * @param name 084 * the meridian name (value) 085 */ 086 Meridian(final String name) 087 { 088 super(name); 089 } 090 } 091 092 /** 093 * Retrieves a <code>TimeOfDay</code> value on a 24-hour clock. 094 * 095 * @param hour 096 * the hour (0-23) 097 * @param minute 098 * the minute (0-59) 099 * @param second 100 * the second (0-59) 101 * @return the time of day 102 */ 103 public static TimeOfDay militaryTime(final int hour, final int minute, final int second) 104 { 105 if ((hour > 23) || (hour < 0)) 106 { 107 throw new IllegalArgumentException("Hour " + hour + " is not valid"); 108 } 109 110 if ((minute > 59) || (minute < 0)) 111 { 112 throw new IllegalArgumentException("Minute " + minute + " is not valid"); 113 } 114 115 if ((second > 59) || (second < 0)) 116 { 117 throw new IllegalArgumentException("Second " + second + " is not valid"); 118 } 119 120 return valueOf(Duration.hours(hour) 121 .add(Duration.minutes(minute)) 122 .add(Duration.seconds(second))); 123 } 124 125 /** 126 * Retrieves the <code>TimeOfDay</code> representing 'now'. 127 * 128 * @return the time of day it is now 129 */ 130 public static TimeOfDay now() 131 { 132 return valueOf(Time.now()); 133 } 134 135 /** 136 * Retrieves the <code>TimeOfDay</code> representing 'now' on the given <code>Calendar</code>. 137 * 138 * @param calendar 139 * the <code>Calendar</code> to use 140 * @return the time of day it is now on the given <code>Calendar</code> 141 */ 142 public static TimeOfDay now(final Calendar calendar) 143 { 144 return valueOf(calendar, Time.now()); 145 } 146 147 /** 148 * Retrieves a <code>TimeOfDay</code> on a 12-hour clock. 149 * 150 * @param hour 151 * the hour (1-12) 152 * @param minute 153 * the minute (0-59) 154 * @param second 155 * the second (0-59) 156 * @param meridian 157 * AM or PM 158 * @return the <code>TimeOfDay</code> value 159 */ 160 public static TimeOfDay time(final int hour, final int minute, final int second, 161 final Meridian meridian) 162 { 163 if (meridian == PM) 164 { 165 if (hour == 12) 166 { 167 return militaryTime(12, minute, second); 168 } 169 else 170 { 171 return militaryTime(hour + 12, minute, second); 172 } 173 } 174 else 175 { 176 if (hour == 12) 177 { 178 return militaryTime(0, minute, second); 179 } 180 else 181 { 182 return militaryTime(hour, minute, second); 183 } 184 } 185 } 186 187 /** 188 * Retrieves a <code>TimeOfDay</code> on a 12-hour clock. 189 * 190 * @param hour 191 * the hour (1-12) 192 * @param minute 193 * the minute (0-59) 194 * @param meridian 195 * AM of PM 196 * @return the <code>TimeOfDay</code> value 197 */ 198 public static TimeOfDay time(final int hour, final int minute, final Meridian meridian) 199 { 200 return time(hour, minute, 0, meridian); 201 } 202 203 /** 204 * Converts a time <code>String</code> and <code>Calendar</code> to a <code>TimeOfDay</code> 205 * instance. 206 * 207 * @param calendar 208 * the <code>Calendar</code> to use when parsing time <code>String</code> 209 * @param time 210 * a <code>String</code> in 'h.mma' format 211 * @return the <code>TimeOfDay</code> on the given <code>Calendar</code> 212 * @throws ParseException 213 */ 214 public static TimeOfDay valueOf(final Calendar calendar, final String time) 215 throws ParseException 216 { 217 synchronized (timeFormat) 218 { 219 synchronized (calendar) 220 { 221 timeFormat.setCalendar(calendar); 222 return new TimeOfDay(timeFormat.parse(time).getTime()); 223 } 224 } 225 } 226 227 /** 228 * Converts a <code>Time</code> instance and <code>Calendar</code> to a <code>TimeOfDay</code> 229 * instance. 230 * 231 * @param calendar 232 * the <code>Calendar</code> to use 233 * @param time 234 * a <code>Time</code> instance 235 * @return the <code>TimeOfDay</code> on the given <code>Calendar</code> 236 */ 237 public static TimeOfDay valueOf(final Calendar calendar, final Time time) 238 { 239 return militaryTime(time.getHour(calendar), time.getMinute(calendar), 240 time.getSecond(calendar)); 241 } 242 243 /** 244 * Converts a <code>Duration</code> instance to a <code>TimeOfDay</code> instance. 245 * 246 * @param duration 247 * the <code>Duration</code> to use 248 * @return the <code>TimeOfDay</code> of the given <code>Duration</code> 249 */ 250 public static TimeOfDay valueOf(final Duration duration) 251 { 252 return new TimeOfDay(duration.getMilliseconds()); 253 } 254 255 /** 256 * Converts a <code>long</code> value to a <code>TimeOfDay</code> instance. 257 * 258 * @param time 259 * the time in milliseconds today 260 * @return the <code>TimeOfDay</code> 261 */ 262 public static TimeOfDay valueOf(final long time) 263 { 264 return new TimeOfDay(time); 265 } 266 267 /** 268 * Converts a <code>String</code> value to a <code>TimeOfDay</code> instance. 269 * 270 * @param time 271 * a <code>String</code> in 'h.mma' format 272 * @return the <code>TimeOfDay</code> 273 * @throws ParseException 274 */ 275 public static TimeOfDay valueOf(final String time) throws ParseException 276 { 277 return valueOf(localtime, time); 278 } 279 280 /** 281 * Converts a <code>String</code> value to a <code>TimeOfDay</code> instance. 282 * 283 * @param time 284 * a <code>Time</code> to convert to <code>TimeOfDay</code> 285 * @return the <code>TimeOfDay</code> in the current time zone 286 */ 287 public static TimeOfDay valueOf(final Time time) 288 { 289 return valueOf(AbstractTime.localtime, time); 290 } 291 292 /** 293 * Private utility constructor forces use of static factory methods. 294 * 295 * @param time 296 * the time today in milliseconds 297 */ 298 private TimeOfDay(final long time) 299 { 300 super(time); 301 302 // A time of day value must be less than 1 day of milliseconds 303 if (Duration.valueOf(time).greaterThan(Duration.ONE_DAY)) 304 { 305 throw new IllegalArgumentException("Time " + this + " is not a time of day value"); 306 } 307 } 308 309 /** 310 * Retrieves the hour of the day. 311 * 312 * @return the hour (0-23) of this <code>TimeOfDay</code> 313 */ 314 public int hour() 315 { 316 return toHours(getMilliseconds()); 317 } 318 319 /** 320 * Retrieves the minute. 321 * 322 * @return the minute (0-59) of this <code>TimeOfDay</code> 323 */ 324 public int minute() 325 { 326 return toMinutes(getMilliseconds()) % 60; 327 } 328 329 /** 330 * Retrieves the next occurrence of this <code>TimeOfDay</code> in local time. 331 * 332 * @return the next occurrence of this <code>TimeOfDay</code> in local time 333 */ 334 public Time next() 335 { 336 return next(AbstractTime.localtime); 337 } 338 339 /** 340 * Retrieves the next occurrence of this <code>TimeOfDay</code> on the given 341 * <code>Calendar</code>. 342 * 343 * @param calendar 344 * the <code>Calendar</code> to use 345 * @return the next occurrence of this <code>TimeOfDay</code> on the given <code>Calendar</code> 346 */ 347 public Time next(final Calendar calendar) 348 { 349 // Get this time of day today 350 final Time timeToday = Time.valueOf(calendar, this); 351 352 // If it has already passed 353 if (timeToday.before(Time.now())) 354 { 355 // Return the time tomorrow 356 return Time.valueOf(calendar, this).add(Duration.ONE_DAY); 357 } 358 else 359 { 360 // Time hasn't happened yet today 361 return timeToday; 362 } 363 } 364 365 /** 366 * Retrieves the second. 367 * 368 * @return the second (0-59) 369 */ 370 public int second() 371 { 372 return toSeconds(getMilliseconds()) % 60; 373 } 374 375 /** 376 * @see Object#toString() 377 */ 378 @Override 379 public String toString() 380 { 381 final int second = second(); 382 return "" + hour() + ":" + minute() + (second != 0 ? ":" + second : ""); 383 } 384 385 /** 386 * Retrieves milliseconds as hours. 387 * 388 * @param milliseconds 389 * milliseconds to convert 390 * @return converted input 391 */ 392 private int toHours(final long milliseconds) 393 { 394 return toMinutes(milliseconds) / 60; 395 } 396 397 /** 398 * Retrieves milliseconds as minutes. 399 * 400 * @param milliseconds 401 * milliseconds to convert 402 * @return converted input 403 */ 404 private int toMinutes(final long milliseconds) 405 { 406 return toSeconds(milliseconds) / 60; 407 } 408 409 /** 410 * Retrieves milliseconds as seconds. 411 * 412 * @param milliseconds 413 * milliseconds to convert 414 * @return converted input 415 */ 416 private int toSeconds(final long milliseconds) 417 { 418 return (int)(milliseconds / 1000); 419 } 420}