Repository
better way to iterate through the list of items in a repository and access specific columns
Nope. We cannot help you on that point as you have not shown or explained your repository code.
I can show you proper JDBC 4.2 code to retrieve a date-only value from a database column of a type akin to the SQL-standard DATE
type.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
Or can someone easily help me fix the code I have so far?
Yes, I can help.
- You are using incorrect syntax.
- You are ignoring crucial issue of time zone.
Use isEqual
method, not ==
The ==
operator on Java tests either:
- If two references both point to the same object, to the same location in memory.
(Generally speaking, this is very rarely needed in most apps. So generally do not use ==
with objects.)
- If two primitives (
int
, boolean
, etc.) have equivalent values.
So the effect is dramatically different between those two. One compares the values of the data you care about (in primitives). The other compares the memory location (a number basically) of a pair of references (pointers) without regard to the data you care about (in objects).
When comparing the value of two objects, call a method. For LocalDate
that would be isEqual
. You can also compare temporally with isBefore
& isAfter
.
So your code:
if ( lic.expiration.minusDays( 30 ) == LocalDate.now() ) { … }
…should be…
if ( lic.expiration.minusDays( 30 ).isEqual( LocalDate.now() ) ) { … }
I would break that down in my own code.
LocalDate today = LocalDate.now() ;
LocalDate thirtyDaysBeforeExpiration = lic.expiration.minusDays( 30 ) ;
if ( thirtyDaysBeforeExpiration.isEqual( today ) ) { … }
Time zone
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of Continent/Region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 2-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( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
So my version of your code would actually be:
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;
LocalDate thirtyDaysBeforeExpiration = lic.expiration.minusDays( 30 ) ;
if ( then.isEqual( today ) ) { … }
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.