Reputation: 375
I'm having trouble getting milliseconds from the epoch out of the string in the example. I have tried this three different ways so far, and the example shows the latest attempt. It always seems to come down to that the TemporalAccessor does not support ChronoField. If I could successfully construct an instance of Instant, I could use toEpochMilli().
String dateStr = "2014-08-16T05:03:45-05:00"
TemporalAccessor creationAccessor = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(dateStr);
Instant creationDate = Instant.from(creationAccessor);
Please give concise answers (don't construct a formatter from scratch) and use only the java 8 standard distribution (I can do it with Joda, but want to avoid dependencies).
Edit: Instant.from in the code above throws: java.time.DateTimeException: Unable to obtain Instant from TemporalAccessor: {OffsetSeconds=-18000},ISO resolved to 2014-08-16T05:03:45 of type java.time.format.Parsed
Upvotes: 14
Views: 18937
Reputation: 340230
Your code is working now, as of Java 8 Update 51 on Mac OS X Mountain Lion. The Answer by Holger that there may have been a bug in earlier versions of Java. Understandable as the java.time framework is brand-new in Java 8.
Here is a modified copy of your code.
String dateStr = "2014-08-16T05:03:45-05:00";
TemporalAccessor creationAccessor = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse( dateStr );
Instant instant = Instant.from( creationAccessor );
long millisSinceEpoch = instant.toEpochMilli( );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant, ZoneOffset.of( "-05:00" ) );
Dump to console.
System.out.println( "dateStr: " + dateStr );
System.out.println( "instant: " + instant );
System.out.println( " millis: " + millisSinceEpoch );
System.out.println( " zdt: " + zdt );
When run.
dateStr: 2014-08-16T05:03:45-05:00
instant: 2014-08-16T10:03:45Z
millis: 1408183425000
zdt: 2014-08-16T05:03:45-05:00
parse(CharSequence text, TemporalQuery<T> query)
You may want to accomplish your parsing using an alternate method.
The class doc for DateTimeFormatter
mentions that the usual way to parse should be a call to DateTimeFormatter::parse(CharSequence text, TemporalQuery<T> query)
rather than DateTimeFormatter::parse(CharSequence text)
.
So instead of this:
String input = "2007-12-03T10:15:30+01:00[Europe/Paris]" ;
TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_DATE_TIME.parse( input ) ;
…do this, where we add a second argument, the argument being a method reference in Java 8 syntax, to call the conversion from
method (in this example, ZonedDateTime :: from
):
String input = "2007-12-03T10:15:30+01:00[Europe/Paris]" ;
ZonedDateTime zdt = DateTimeFormatter.ISO_DATE_TIME.parse( input , ZonedDateTime :: from ) ;
Dump to console.
System.out.println("input: " + input );
System.out.println(" zdt: " + zdt );
When run.
input: 2007-12-03T10:15:30+01:00[Europe/Paris]
zdt: 2007-12-03T10:15:30+01:00[Europe/Paris]
Upvotes: 11
Reputation: 298579
This seems to be a bug which I found in all tested versions before and including jdk1.8.0_20b19
but not in the final jdk1.8.0_20
. So downloading an up-to-date jdk version would solve the problem. It’s also solved in the most recent jdk1.9.
Note that the good old Java 7 way works in all versions:
long epochMillis = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")
.parse(dateStr).getTime();
It also supports getting an Instant
:
Instant i=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").parse(dateStr).toInstant();
long epochMillis = i.toEpochMilli();
But, as said, a simple update makes your Java 8 code working.
Upvotes: 11
Reputation: 34677
Instant.from(creationAccessor).toEpochMili() should sort you, at least according to the ThreeTen javadoc for TemporalInstant. ThreeTen is the reference implementation of javax.time. Let me know if this works for you or not by leaving a comment.
Upvotes: 0
Reputation: 11815
Since instant can't properly be represented using a long (they've designed the API to not have Y 2040 issues, when a long is no longer sufficient), you have to use a combination of two methods
getEpochSecond()
and
getNano()
The former gets you the # of seconds from epoch, and the latter gives you the # of nanoseconds that have passed since that same second.
Upvotes: 0