2016-12-26 10 views
1

SimpleDateFormatを使用してDateにStringを解析しようとしていますが、Dateが間違っています。SimpleDateFormatが別の日付に構文解析しています

String dataNascimentoValue = "Thu Jan 01 00:00:00 GMT 1970"; 
SimpleDateFormat converter = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); 

Date date = new Date(); 

converter.setLenient(false); 
date = converter.parse(dataNascimentoValue); //at this moment It generates //a wrong Date: Wed Dec 31 19:00:00 EST 1969 

SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy"); 
String formatedDate = formatter.format(date); 

私はすでに私のSimpleDateFormatでロケールを入れてみましたが、うまくいきませんでした。 StringをDateに構文解析したいのですが、後で書式を設定する必要があるためです。

助けが必要ですか?

Screenshot of my try using the Locale.US

+0

あなたはスクリーンショットの値について確かですか? 'new Date()'で作成されたインスタンスは、1969年の日付として値を持つことができますか? – davidxxx

+0

この値はありませんでしたが、次の行からこの値をとります: "date = converter.parse(dataNascimentoValue);" これは私の問題です、この行の後、私はこの ".parse()"メソッドを使用すると、私の日付の値が間違った値をとります。 – BrunoMori

+0

FYI、[java.util.Date'](https://docs.oracle.com/javase/9​​/docs/api/java/util/Date.html)などの面倒な古い日時クラス、 'java.util.Calendar'](https://docs.oracle.com/javase/9​​/docs/api/java/util/Calendar.html)、' java.text.SimpleDateFormat'は現在[レガシー]です( [* java.time *](https://docs.oracle.com/javase/9​​/docs/api/java/time/package-system)に置き換えられました(https://en.wikipedia.org/wiki/Legacy_system) summary.html)Java 8およびJava 9に組み込まれたクラス。[* Tutorial * by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html)を参照してください。 –

答えて

0

TL; DR

ZonedDateTime.parse ( 
    "Thu Jan 01 00:00:00 GMT 1970" , 
    DateTimeFormatter.ofPattern ("EEE MMM dd HH:mm:ss zzz uuuu" , Locale.CANADA)      
) 

機能、ないバグ

これら二つの文字列:

  • Thur Jan 01 00:00:00 GMT 1970
  • Wed Dec 31 19:00:00 EST 1969

... 非常に同じ瞬間、タイムライン上の同じポイントを表します。だからここに問題はない。あなたは文書化されている通り正しい動作をしています。

ESTは、米国とカナダの多くの東部地域で使用されるタイムゾーンを指します。そのようなゾーンは、UTC(GMT)より5時間遅れています。ミッドナイトマイナス5時間は、前日の午後7時(19:00)です。 wall-clock timeとは異なりますが、宇宙の歴史において同じ瞬間です。

Dateなどのレガシー日付時刻クラスで多くの貧しいデザインの選択肢の一つは、動的にUTCにそう常にある値の表現を生成toStringの呼び出し中にJVMの現在のデフォルトのタイムゾーンを適用しています。実際にDateが常にUTCである場合、この動作がタイムゾーンを持つという錯覚を作り出すので、非常に混乱します。もっと紛らわしいのは、実際にはです。Date内部の深い時間帯は、いくつかの内部目的のために使用されていますが、そのゾーンのゲッターやセッターはありません。このクラスはひどい混乱です。避けてください。

あなたのJVMがESTで現在のデフォルトのタイムゾーンを持っていると推測できます。あなたはjava.timeクラスに取って代わら面倒な古い日付時刻クラス、今の遺産を、使用している

java.timeを使用して

。これらのレガシークラスは避けてください。 java.timeクラスのみを使用してください。日付時刻文字列を解析する際に

は必ずLocaleを指定します。省略した場合、JVMの現在のデフォルト値Localeは、(a)テキストの翻訳のための英語などの人間言語の決定、および(b)省略語、大文字小文字、句読点などの問題を決定する文化的規範の決定に使用されます。

String input = "Thu Jan 01 00:00:00 GMT 1970"; 
DateTimeFormatter f = DateTimeFormatter.ofPattern ("EEE MMM dd HH:mm:ss zzz uuuu" , Locale.CANADA); 
ZonedDateTime zdt = ZonedDateTime.parse (input , f); 

zdt.toString():1970-01-01T00:00Z [GMT]

あなたは他のタイムゾーンに調整することができます。 ZoneIdを適用して別のZonedDateTimeを取得します。

は、America/MontrealAfrica/Casablanca、又はPacific/Aucklandとして、continent/regionの形式でproper time zone nameを指定します。 ESTまたはISTのような3〜4文字の略語は、ではなく、のように、標準化されておらず、ユニークではない(!)と使用しないでください。

ZoneId z = ZoneId.of("America/Montreal"); 
ZonedDateTime zdtMontreal = zdt.withZoneSameInstant(z); 

zdtMontreal.toString():1969-12-31T19:00〜05:00 [アメリカ/モントリオール]

java.timeクラスにtoString方法は、より賢明かつ明確です日時値のテキスト表現を生成するときは、標準のISO 8601形式を使用します。

live code at IdeOne.comを参照してください。 java.timeについて


java.timeフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは、java.util.DateCalendar、& SimpleDateFormatなど、面倒な古いlegacy日時クラスに取って代わります。

maintenance modeにあるJoda-Timeプロジェクトは、java.timeクラスへの移行を推奨しています。

詳しくはOracle Tutorialをご覧ください。そして、多くの例と説明のためにStack Overflowを検索してください。仕様はJSR 310です。

ここで、java.timeクラスを取得するには?

  • Java SE 8SE 9以降
    • 内蔵しています。
    • バンドルされた実装の標準Java APIの一部です。
    • Java 9には、いくつかのマイナーな機能と修正が加えられています。
  • Java SE 6SE 7
    • java.time機能の多くはThreeTen-BackportのJava 6 & 7に戻って、移植されます。
  • Android
      ThreeTenABP
    • プロジェクトは、具体的にはAndroid用(上記)ThreeTen-バックポートを適応させます。
    • How to use ThreeTenABP…を参照してください。

ThreeTen-Extraプロジェクトでは、追加のクラスでjava.timeを拡張します。このプロジェクトは、将来のjava.timeへの追加の可能性を証明する土台です。ここでは、IntervalYearWeekYearQuartermoreなどの便利なクラスがあります。

+0

Basil Bourque、ご説明いただきありがとうございます! 残念ながら私のプロジェクトはJava 6で作成されていますが、新しいものを使用しないでこの状況を "解決"する方法はいくつかあります。 – BrunoMori

+0

@ブルノモリ私の答えをもっと慎重に読んでください。 "About java.time"セクションの2番目の外側の箇条書きに特に注意してください。 –

0

あなたは今までに文字列を解析するために、このメソッドを使用することができます。

private static final SimpleDateFormat _simpleDateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 

public static Date stringToJavaDateOnly(String dateStr) 
      throws ParseException { 
     return _simpleDateTimeFormat.parse(dateStr); 
    } 
+0

が正しくありません。この形式は、入力文字列の形式にも近くない。 –

関連する問題