tl;dr
Rather than using strings, use java.time objects (LocalDate
specifically) exchanged with your database via JDBC 4.2 or later.
myResultSet.getObject( // Exchange modern java.time objects with your database.
"START_DATE" ,
LocalDate.class
) // Returns a `LocalDate` object.
.format( // Generate a `String` representing textually the content of this `LocalDate`.
DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US )
)
23-Jan-2018
Being immutable objects, the java.time objects are thread-safe by design. You can cache the java.time objects for use across threads.
java.time
Making SimpleDateFormat thread safe
Don’t.
Use the modern java.time classes that years ago supplanted the troublesome old legacy date-time classes such as SimpleDateFormat
, java.util.Date
, java.sql.Date
, and Calendar
.
The java.time classes are designed to be thread-safe. They use immutable objects pattern, to return fresh objects based on the values of an original rather than “mutating” (altering) the original.
Use smart objects, not dumb strings
I see no reason for using strings in your example code: Not in your database access code, not in your business object (Trade
).
JDBC
As of JDBC 4.2, we can exchange java.time objects with the database. For a database column of a type akin to the SQL-standard DATE
, use the class LocalDate
. The LocalDate
class represents a date-only value without time-of-day and without time zone.
myPreparedStatement.setObject( … , myLocalDate ) ;
Retrieval.
LocalDate myLocalDate = myResultSet.getObject( … , LocalDate.class ) ;
Business object
Your Trade
class should be holding member variables startDate
& endDate
as LocalDate
objects, not strings.
public class Trade {
private LocalDate startDate ;
private LocalDate endDate ;
…
// Getters
public LocalDate getStartDate() {
return this.startDate ;
}
public LocalDate getEndDate() {
return this.endDate;
}
public Period getPeriod() { // Number of years-months-days elapsed.
return Period.between( this.startDate , this.endDate ) ;
}
// Setters
public void setStartDate( LocalDate startDateArg ) {
this.startDate = startDateArg ;
}
public void setEndDate( LocalDate endDateArg ) {
this.endDate = endDateArg ;
}
@Override
public toString() {
"Trade={ " + "startDate=" + this.startDate.toString() …
}
…
}
No need for strings, no need for formatting patterns.
Strings
To exchange or store date-time values as text, use the standard ISO 8601 formats rather than a custom format as seen in your Question.
The java.time classes use the ISO 8601 formats by default when parsing/generating strings. So no need to specify a formatting pattern.
LocalDate ld = LocalDate.parse( "2018-01-23" ) ; // January 23, 2018.
String s = ld.toString() ; // Outputs 2018-01-23.
For presentation in a user-interface, let java.time automatically localize. To localize, specify:
FormatStyle
to determine how long or abbreviated should the string be.
Locale
to determine:
- The human language for translation of name of day, name of month, and such.
- The cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
Example:
Locale l = Locale.CANADA_FRENCH ;
DateTimeFormatter f =
DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL )
.withLocale( l ) ;
String output = ld.format( f ) ;
mardi 23 janvier 2018
The DateTimeFormatter
class is thread-safe, by design, as an immutable object. You could hold one instance to be used across threads.
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.