Avoid legacy date-time classes
Avoid the troublesome old legacy date-time classes such as java.util.Date
. Use only java.time classes. Likewise, the Joda-Time project too is now supplanted by the java.time classes, both having been created by the same man, Stephen Colebourne.
Instant
Convert your Date
to Instant
. Both classes represent a moment in UTC, always in UTC, despite the Date::toString
method lying to you.
Convert using new methods added to the old classes.
Instant instant = myJavaUtilDate.toInstant() ;
ZonedDateTime
Apply a time zone or offset-from-UTC for the wall-clock time intended by you pair of time-of-day strings. Did you mean 5 PM in New York, or 5 PM in Tunisia, or 5 PM in India?
Specify a proper time zone name in the format of continent/region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 3-4 letter abbreviation such as EST
or IST
as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ; // Or "Pacific/Auckland" etc.
ZonedDateTime zdt = instant.atZone( z ) ;
Extract the time-of-day without date and without zone.
LocalTime lt = zdt.toLocalTime() ;
LocalTime
Parse your limits as LocalTime
objects.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "h:mm a" , Locale.US ) ;
LocalTime start = LocalTime.parse( "5:03 PM" , f ) ;
LocalTime stop = LocalTime.parse( "5:11 PM" , f ) ;
Half-Open
Generally best to use Half-Open approach to defining a span of time. This means the beginning is inclusive while the ending is exclusive. So test for “less than eleven past five” if you want to exclude all of the tenth minute.
Tip: A shorter way of saying “Is equal to or is after” is “Is not before”.
if ( ( ! lt.isBefore( start ) ) && lt.isBefore( stop ) ) {
zdt = zdt.with( stop ) ; // Change to a different time-of-day.
}
If that time-of-day on that date in that zone is invalid, the ZonedDateTime
class makes an adjustment as needed.
Database
For saving to a database in a column of type TIMESTAMP WITH TIME ZONE
, let's adjust our moment into UTC by extracting an Instant
.
Instant instantForDatabase = zdt.toInstant() ;
…
myPreparedStatement.setObject( … , instantForDatabase ) ;
Retrieval from database.
Instant instantFromDatabase = myResultSet.getObject( … , Instant.class ) ;
ZoneId zMontreal = ZoneId.of( "America/Montreal" ) ; // Or "Asia/Kolkata" etc.
ZondDateTime zdtMontreal = instantFromDatabase.atZone( zMontreal ) ;
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.