tl;dr
Do not conflate a date-time object with a string representing its value. A date-time object has no “format”.
ZonedDateTime.now( // Instantiate a `ZonedDateTime` object capturing the current moment.
ZoneId.of( "Africa/Tunis" ) // Assign this time zone through which we see the wall-clock time used by the people of this particular region.
).format( // Generate a string representing the value of this `ZonedDateTime` object.
DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ) // Define a formatting pattern to match your desire.
)
2018-03-10 07:36:23
Calling ZonedDateTime::toString
generates a string in standard ISO 8601 format.
2018-03-10T07:36:23.595362+01:00[Africa/Tunis]
Date-time object has no “format”
You are confusing a date-time object in Java, or a date-time value stored in a database, with a textual representation. You can generate a string from a date-time object (or database value), but that string is separate and distinct from the value it represents. Do not conflate a string with its generating creator.
java.time
Avoid using the troublesome old date-time classes such as Date
, Calendar
, and SimpleDateFormat
. Instead, use Instant
, ZonedDateTime
, and DateTimeFormatter
classes, respectively.
If you have an input string such as 2014-10-31 04:23:42
, replace the SPACE in the middle with a T
to comply with ISO 8601 standard format. The java.time classes use ISO 8601 formats by default when parsing/generating strings.
String input = "2014-10-31 04:23:42".replace( " " , "T" ) ;
That input lacks any indicator of time zone or offset-from-UTC. So parse as a LocalDateTime
which purposely lacks any concept of zone/offset.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
ldt.toString(): 2014-10-31T04:23:42
A LocalDateTime
does not represent a moment, is not a point on the timeline. To determine an actual moment, you must supply the context of a zone or offset.
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ; // Now we have an actual moment, a point on the timeline.
To capture the current moment in UTC, use Instant
.
Instant instant = Instant.now() ;
Adjust into another zone.
ZonedDateTime zdt = instant.atZone( z ) ;
zdt.toString(): 2018-03-10T07:36:23.595362+01:00[Africa/Tunis]
I do not recommend generating strings lacking an indicator of zone/offset. But if you insist, use the built-in DateTimeFormatter
and then replace the T
in the middle with a SPACE to get your desired format.
String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ).replace( "T" , " " ) ;
2018-03-10 07:36:23.595362
If you really do not want the fractional second, then define your own formatting pattern.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ) ;
String output = zdt.format( f ) ;
2018-03-10 07:36:23
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.