I need to append 23 Hrs and 59 mins in the date using the Java calendar class. e.g. 17/03/2022 - has java Date as a datatype - mapped to Date in Oracle need to be stored in the database as 17/03/2022 23.59.00 - has Timestamp as data type.
I got the following function which works in most cases, but sometimes the date goes to the next day with the timestamp of 00.00.00 .
public Date addHoursToJavaUtilDate(Date date, int hours,int mins) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.HOUR_OF_DAY, hours); //hours = 23
calendar.add(Calendar.MINUTE, mins); //mins = 59
return (Date) calendar.getTime();
}
Why does it works in most of the cases but not all the time? Will reducing the number of mins to 30 will help me?
CodePudding user response:
Do you not have the chance to use java.time.*
classes?
I know you specified Calendar
usage, but notice how much simplicity you're missing: (written in Kotlin for easier readability)
val yourDate: LocalDateTime = ... // (or if you have TimeZone info, it would be `ZonedDateTime`)
val newDate = yourDate.plusHours(23).plusMinutes(59)
that's it.
CodePudding user response:
You are using terrible date-time classes that were supplanted years ago by the modern java.time classes defined in JSR 310.
Calendar
, actually GregorianCalendar
, was replaced by ZonedDateTime
.
Data and time
Capturing the current moment requires a time zone. For any given moment the date and the time can vary around the globe by time zone.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
You want to set the time of day to 23:59:00. We can produce a new ZonedDateTime
object based on the old one but with a different time of day. Be aware that your specified time of day will be altered if not valid on that date in that zone, because of anomalies such as Daylight Saving Time (DST).
LocalTime lt = LocalTime.of( 23 , 59 ) ;
ZonedDateTime zdt2359 = zdt.with( lt ) ;
Alternatively, you could capture the current date only. Then assemble a ZonedDateTime
from the three parts of date, time, and zone.
LocalDate ld = LocalDate.now ( z ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
Database access
For database access, do not use legacy class Timestamp
. Use OffsetDateTime
to record a moment in SQL databases.
Write this value to a database column of a type akin to the SQL-standard type TIMESTAMP WITH TIME ZONE
.
OffsetDateTime odt = zdt2359.toOffsetDateTime() ;
myPreparedStatement.setObject( … , odt ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Caveat: If you are trying to represent the end of a day, your 23:59
is the wrong approach. You are missing the last minute of the day. And some dates in some zones are not 24 hours long. Instead, learn about tracking time with Half-Open approach.