例の文字列からエポックからミリ秒を取得するのに問題があります。私はこれまでにこの3つの異なる方法を試しましたが、例は最新の試みを示しています。 TemporalAccessor は ChronoField をサポートしていないことに常になりそうです。 Instantのインスタンスを正常に構築できた場合は、 toEpochMilli() を使用できます。
String dateStr = "2014-08-16T05:03:45-05:00"
TemporalAccessor creationAccessor = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(dateStr);
Instant creationDate = Instant.from(creationAccessor);
簡潔な回答を提供し(フォーマッターを最初から作成しないでください)、Java 8標準ディストリビューション(Jodaで実行できますが、依存関係を避けたい)のみを使用してください)。
編集:上記のコードのInstant.fromは次をスローします: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
これは、jdk1.8.0_20b19
を含む以前のすべてのテスト済みバージョンで見つかったバグのようですが、最終的なjdk1.8.0_20
では見つかりませんでした。したがって、 最新のjdkバージョンをダウンロードする で問題が解決します。最新のjdk1.9でも解決されています。
古き良きJava7の方法は、すべてのバージョンで機能することに注意してください。
long epochMillis = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")
.parse(dateStr).getTime();
また、Instant
の取得もサポートしています。
Instant i=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").parse(dateStr).toInstant();
long epochMillis = i.toEpochMilli();
ただし、前述のように、簡単な更新でJava8コードが機能します。
Java 8 Mac OS X Mountain Lionのアップデート51)の時点で、コードは現在機能しています。 Answer by Holger 以前のバージョンのJavaのバグ。Java.timeフレームワークはJava 8)でまったく新しいため、理解できます。
これがあなたのコードの修正されたコピーです。
_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" ) );
_
コンソールにダンプします。
_System.out.println( "dateStr: " + dateStr );
System.out.println( "instant: " + instant );
System.out.println( " millis: " + millisSinceEpoch );
System.out.println( " zdt: " + zdt );
_
実行時。
_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)
別の方法を使用して解析を実行することをお勧めします。
DateTimeFormatter
のクラスドキュメントには、通常の解析方法は DateTimeFormatter::parse(CharSequence text, TemporalQuery<T> query)
ではなく DateTimeFormatter::parse(CharSequence text)
の呼び出しである必要があると記載されています。
したがって、これの代わりに:
_String input = "2007-12-03T10:15:30+01:00[Europe/Paris]" ;
TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_DATE_TIME.parse( input ) ;
_
…これを行うには、2番目の引数を追加します。引数は メソッド参照in Java 8構文 で、変換from
メソッドを呼び出します(この例、_ZonedDateTime :: from
_):
_String input = "2007-12-03T10:15:30+01:00[Europe/Paris]" ;
ZonedDateTime zdt = DateTimeFormatter.ISO_DATE_TIME.parse( input , ZonedDateTime :: from ) ;
_
コンソールにダンプします。
_System.out.println("input: " + input );
System.out.println(" zdt: " + zdt );
_
実行時。
_input: 2007-12-03T10:15:30+01:00[Europe/Paris]
zdt: 2007-12-03T10:15:30+01:00[Europe/Paris]
_
Instant.from(creationAccessor).toEpochMili()は、少なくとも TemporalInstantのThreeTen javadoc に従ってソートする必要があります。 ThreeTen はjavax.timeのリファレンス実装です。コメントを残して、これがうまくいくかどうか教えてください。
インスタントはlongを使用して適切に表現できないため(longでは不十分な場合にY 2040の問題が発生しないようにAPIを設計している)、2つの方法を組み合わせて使用する必要があります
getEpochSecond()
そして
getNano()
前者はエポックからの秒数を取得し、後者は同じ秒から経過したナノ秒数を取得します。