TL;DR
String gmtTimestamp = "2017-03-12 02:38:30.417000000";
DateTimeFormatter dtf
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSSSSS");
Instant i1 = LocalDateTime.parse(gmtTimestamp, dtf)
.atOffset(ZoneOffset.UTC)
.toInstant();
System.out.println(i1);
This prints
2017-03-12T02:38:30.417Z
The implicit call to Instant.toString()
produces date and time in UTC (for our purpose the same as GMT), so you recognize the date and time from your GMT string.
java.time
I recommend you drop the java.sql.Timestamp
class. It is long outdated, and today we have so much better in java.time
, the modern Java date and time API. The original purpose of Timestamp
was to store and retrieve date-time values to and from SQL databases. With a sufficiently new JDBC driver (JDBC 4.2), you can and will want to take advantage of two classes from java.time
for that purpose: Instant
for a point on the timeline and LocalDateTime
for date and time without time zone.
In case you do need a Timestamp
(for instance for a legacy API or an older JDBC driver you don’t want to upgrade just now), convert the Instant
from above to Timestamp
just before handing it to the legacy API or the database:
Timestamp ts1 = Timestamp.from(i1);
System.out.println(ts1);
Running in America/Chicago time zone this prints:
2017-03-11 20:38:30.417
Timestamp.toString()
grabs the JVM’s time zone setting and outputs the date and time in this time zone (which may be confusing).
What was happening in your code snippet?
FastDateFormat
uses SimpleDateFormat
format patterns. In SimpleDateFormat
and FastDateFormat
capital S
means milliseconds. so 417000000 was taken as milliseconds (where you intended 417 milliseconds), it is rpughly the same as 4 days 20 hours, which were added to the date-time value up to the seconds. I reproduced your result using a SimpleDateFormat
and setting my JVM to America/Chicago time zone. Other time zones that are -5 hours from UTC in March will produce the same result. Since the Timestamp
was printed at offset -5:00, the apparent difference in the output was a bit less than the real difference of 4 days 20 hours, “only” 4 days 15 hours.
By contrast, though the modern DateTimeFormatter
mostly uses the same format pattern letters, to it capital S
means fraction of second, which is why we get 30.417 seconds as expected and desired.
Quotes
All patterns are compatible with SimpleDateFormat (except time zones
and some year patterns - see below).
(FastDateFormat
documentation)
S Millisecond Number 978
(SimpleDateFormat
documentation)