2

I am using the Calendar object. The timestamp formatting I am using uses year, day, hour, and minute. However there are cases where I need to set these to extreme values for a given day.

I can set a Calendar to the first possible time of the day by setting Calendar.HOUR and Calendar.MINUTE to 0 (I think).

What is the correct value for the last minute of the day? Calendar.HOUR set to 23 and Calendar.MINUTE set to 59?

user6261756
  • 147
  • 1
  • 7
  • Use `HOUR_OF_DAY`. – rgettman Apr 28 '16 at 17:51
  • @rgettman As opposed to HOUR? Why? – user6261756 Apr 28 '16 at 17:52
  • Please see [Set time to 00:00:00](http://stackoverflow.com/questions/17821601/set-time-to-000000) or the [`Calendar` Javadocs](https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html). – rgettman Apr 28 '16 at 17:54
  • It looks like SimpleDateFormat itself has 1:00 = 1 am, 24:00 = midnight. It does not appear to use 0 for an hour. – user6261756 Apr 28 '16 at 17:55
  • 1
    @user6261756 Yes. [*Field number for get and set indicating the hour of the morning or afternoon.*](https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#HOUR). See the difference in the definition of `HOUR` and `HOUR_OF_DAY` [(Field number for get and set indicating the hour of the day.)](https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#HOUR_OF_DAY) – dsh Apr 28 '16 at 17:56
  • Some dates in some time zones may not have an hour 23, so there would be no 23:59. Let *java.time* classes determine. – Basil Bourque May 26 '19 at 20:06

2 Answers2

1

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 ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

In a word - yes. The last minute of the day has the hour set to 23 and the minute set to 59. It begins with the seconds set to 0 and ends with them set to 59.

Mureinik
  • 297,002
  • 52
  • 306
  • 350