Other answers are correct, especially the java.time answer by arganzheng. As some mentioned, you should avoid the old java.util.Date/.Calendar classes as they are poorly designed, confusing, and troublesome. They have been supplanted by the java.time classes.
Let me add notes about strategy around handling midnight and spans of time.
Half-Open
In date-time work, spans of time are often defined using the “Half-Open” approach. In this approach the beginning is inclusive while the ending is exclusive. This solves problems and if used consistently makes reasoning about your date-time handling much easier.
One problem solved is defining the end of the day. Is the last moment of the day 23:59:59.999
(milliseconds)? Perhaps, in the java.util.Date class (from earliest Java; troublesome – avoid this class!) and in the highly successful Joda-Time library. But in other software, such as database like Postgres, the last moment will be 23:59:59.999999
(microseconds). But in other software such as the java.time framework (built into Java 8 and later, successor to Joda-Time) and in some database such the H2 Database, the last moment might be 23:59.59.999999999
(nanoseconds). Rather than splitting hairs, think in terms of first moment only, not last moment.
In Half-Open, a day runs from the first moment of one day and goes up to but does not include the first moment of the following day. So rather than think like this:
…from today at 00:00am (midnight early this morning) to 12:00pm (midnight tonight).
…think like this…
from first moment of today running up to but not including first moment of tomorrow:
( >= 00:00:00.0
today AND < 00:00:00.0
tomorrow )
In database work, this approach means not using the BETWEEN
operator in SQL.
Start of day
Furthermore, the first moment of the day is not always the time-of-day 00:00:00.0
. Daylight Saving Time (DST) in some time zones, and possibly other anomalies, can mean a different time starts the day.
So let the java.time classes do the work of determining the start of a day with a call to LocalDate::atStartOfDay( ZoneId )
. So we have to detour through LocalDate
and back to ZonedDateTime
as you can see in this example code.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime tomorrowStart = todayStart.plusDays( 1 );
Note the passing of the optional ZoneId
. If omitted your JVM’s current default time zone is applied implicitly. Better to be explicit.
Time zone is crucial to date-time work. The Question and some other Answers are potentially flawed because the do not consciously handle time zone.
Convert
If you must use a java.util.Date or .Calendar, look for new conversion methods added to those old classes.
java.util.Date utilDate = java.util.Date.from( todayStart.toInstant() );
java.util.GregorianCalendar gregCal = java.util.GregorianCalendar.from( todayStart );
Span of time
By the way, if you are doing much work with spans of time take a look at:
Duration
Period
Interval
The Interval
class is found in the ThreeTen-Extra project, an extension to the java.time framework. This project is the proving ground for possible future additions to java.time.
Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.