Use DateUtils
to round Date
objects to the nearest Calendar
field.
DateUtils.round()
can round to almost every
Calendar
field, including
Calendar.SECOND
,
Calendar.MINUTE
, Calendar.HOUR
,
Calendar.DAY_OF_MONTH
,
Calendar.MONTH
, and
Calendar.YEAR
. The following example demonstrates
the use of DateUtils.round( )
:
import org.apache.commons.lang.time.FastDateFormat; import org.apache.commons.lang.time.DateFormatUtils; import org.apache.commons.lang.time.DateUtils; FastDateFormat dtFormat = DateFormatUtils.ISO_DATETIME_FORMAT; Date now = new Date( ); Date nearestHour = DateUtils.round( now, Calendar.HOUR ); Date nearestDay = DateUtils.round( now, Calendar.DAY_OF_MONTH ); Date nearestYear = DateUtils.round( now, Calendar.YEAR ); System.out.println( "Now: " + dtFormat.format( now ) ); System.out.println( "Nearest Hour: " + dtFormat.format( nearestHour ) ); System.out.println( "Nearest Day: " + dtFormat.format( nearestDay ) ); System.out.println( "Nearest Year: " + dtFormat.format( nearestYear ) );
This example creates an object representing the current time and
rounds this date to the nearest hour, day, and year. Assuming that
the current date is March 28, 2004, and the current time is 1:48
P.M., this program creates the following output using the
FastDateFormat
class from the previous recipe:
Now: 2004-03-28T13:48:12 Nearest Hour: 2004-03-28T14:00:00 Nearest Day: 2004-03-29T00:00:00 Nearest Year: 2004-01-01T00:00:00
If you are creating a system to record the time of an event, and you
are not certain exactly when that event happened, it is appropriate
to round that date and time to an approximate value. Are you certain
that you woke up at 9:02 A.M., 23 seconds, and 879 milliseconds? Or,
is it more likely that you remember that you woke up around 9 A.M.?
It would be appropriate to round this time to the
Calendar.MINUTE
or
Calendar.HOUR
field at the very
least—recording a general time, such as
“around 9 A.M.” In the following
example, DateUtils.round( )
calculates an
approximate time:
// Rounding to the nearest hour Date wokeUp = new Date( ); Date wokeUpAround = DateUtils.round( now, Calendar.HOUR );
If your wokeUp
Date
object is
1:31 P.M., then wokeUpAround
will be equal to 2:00
P.M. But, if you woke up at 1:15 P.M., your
wokeUpAround
object would then be rounded down to
1:00 P.M. When you round or truncate to a field, all of the date
fields less significant than the specified field are set to zero. In
this example, rounding to an hour causes the minutes, seconds, and
milliseconds to be set to zero. Rounding a Date
to
a Calendar.YEAR
sets the day of the year to one
and the time to the first instance of the nearest year:
Date now = new Date( ) Date nearestYear = DateUtils.round( now, Calendar.YEAR );
This previous code rounds to the nearest year, and if
now
is 15 May 2004, the resulting
Date
will correspond to the first instance of
2004. Alternatively, if now
is 15 July 2004, the
resulting Date
will be the first instance of 2005.
DateUtils.round( )
works with the following field
values, listed in order of significance:
Calendar.MILLISECOND
Calendar.SECOND
Calendar.MINUTE
Calendar.HOUR_OF_DAY
andCalendar.HOUR
Calendar.DATE
,Calendar.DAY_OF_MONTH
, andCalendar.AM_PM
Calendar.MONTH
DateUtils.SEMI_MONTH
Calendar.YEAR
Calendar.ERA
DateUtils
introduces a
DateUtils.SEMI_MONTH
field, which will cause dates
to be rounded to the middle or beginning of a month. In
DateUtils
, the middle of the month is defined as
the 15th day of the month with the second half of the month starting
at midnight on the 16th day of the month:
Calendar cal = Calendar.getInstance( ); cal.set( 2004, Calendar.MARCH, 5, 10, 2, 2 ); System.out.println( DateUtils.round( cal.getTime( ) , DateUtils.SEMI_MONTH ) );
This code will print out Mon Mar 01 00:00:00 CST
2004
as the 5th of March and is closer to the beginning of
the month than it is to the middle of the month. If the
Calendar
object was March, 14th, 2004, and it had
been rounded to a DateUtils.SEMI_MONTH
, the
rounded date would have been set to midnight on March 16th. One would
think that the middle of March is the 15th? Isn’t
that date the famous Ides of March—the date on which Brutus
betrayed Caesar? According to DateUtils
, the first
half of the month ends at 11:59 P.M. on the 15th of the month; the
DateUtils.round( )
method returns the first
instant of the beginning of the second half of March: March
16 12:00:00.000 A.M
.
The more you work with Java’s
Date
and Calendar
object, the
more you will curse the J2SE. If your frustration is boiling over,
take a look at Joda.
Joda contains an entire package devoted to date, time, and duration
formatting, and it is not based on the Date
or
Calendar
classes. For more information about Joda,
take a look at the Joda project page at: http://www.joda.org/.
Get Jakarta Commons Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.