java.time
The terrible Calendar
and GregorianCalendar
were supplanted years ago by the modern java.time classes defined in JSR 310.
To get the first moment of the day, start with a date-only, a LocalDate
.
LocalDate ld = LocalDate.of( 2019 , Month.JANUARY , 23 ) ;
To consider the time-of-day, we must have a time zone. Days do not always start at 00:00:00. On some dates in some zones, the day may start at a time such as 01:00:00. So let java.time determine the first moment of the day for the time zone of interest.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtFirstMoment = ld.atStartOfDay( z ) ;
As for the last moment of the day, that is problematic. The fraction of the last second of the last minute of the last hour is infinitely divisible. It could be something like 23:59:59.999 or 23:59:59.999999 or 23:59:59.999999999.
Generally it is better to work with spans of time defined as Half-Open. This means the beginning is inclusive while the ending is exclusive. For example, when we say the students’ lunch break is noon to 1 PM, we mean they should have their tushies in their seats before the bell strikes. So lunch starts at 12:00:00.0 and runs up to, but does not include, 13:00:00.0. Similarly, a week starts on a Monday and runs up to, but does not include, the following Monday.
ZonedDateTime zdtFirstMomentNextDay = zdtFirstMoment.plusDays( 1 ) ;
If you insist on getting the last minute of the day, subtract a minute from the first moment.
ZonedDateTime zdtLastMinute = zdtFirstMomentNextDay.minusMinutes( 1 ) ;
A day is not always 24 hours. It can be 23, 23.5, 25, or other numbers of hours long. To calculate the elapsed time, use Duration
.
Duration d = Duration.between( zdtFirstMoment , zdtFirstMomentNextDay ) ;
To represent this span-of-time as a pair of moments attached to the timeline, add the ThreeTen-Extra library to your project. Then use its Interval
class. Adjust each ZonedDateTime
to UTC by extracting an Instant
object. Instant
represents a moment in UTC.
Interval interval = Interval.of(
zdtFirstMoment.toInstant() ,
zdtFirstMomentNextDay.toInstant()
) ;
If you must have a Calendar
object, convert from ZonedDateTime
using the new conversion methods added to the old classes. In this case, GregorianCalendar.from()
.
Calendar c = GregorianCalendar.from( zdtFirstMomentNextDay ) ;