新しい日時APIを使用して日付をフォーマットする


118

私は新しい日付時間APIで遊んでいましたが、これを実行すると:

public class Test {         
    public static void main(String[] args){
        String dateFormatted = LocalDate.now()
                                        .format(DateTimeFormatter
                                              .ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(dateFormatted);
    }
}

それは投げます:

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay
    at java.time.LocalDate.get0(LocalDate.java:680)
    at java.time.LocalDate.getLong(LocalDate.java:659)
    at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
    at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2543)
    at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
    at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1745)
    at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1719)
    at java.time.LocalDate.format(LocalDate.java:1685)
    at Test.main(Test.java:23)

LocalDateクラスのソースコードを見ると、次のことがわかります。

  private int get0(TemporalField field) {
        switch ((ChronoField) field) {
            case DAY_OF_WEEK: return getDayOfWeek().getValue();
            case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((day - 1) % 7) + 1;
            case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
            case DAY_OF_MONTH: return day;
            case DAY_OF_YEAR: return getDayOfYear();
            case EPOCH_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'EpochDay' for get() method, use getLong() instead");
            case ALIGNED_WEEK_OF_MONTH: return ((day - 1) / 7) + 1;
            case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1;
            case MONTH_OF_YEAR: return month;
            case PROLEPTIC_MONTH: throw new UnsupportedTemporalTypeException("Invalid field 'ProlepticMonth' for get() method, use getLong() instead");
            case YEAR_OF_ERA: return (year >= 1 ? year : 1 - year);
            case YEAR: return year;
            case ERA: return (year >= 1 ? 1 : 0);
        }
        throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
    }

ドキュメントに記載されているように:

このメソッドは、クラスのドキュメントで説明されているように、文字と記号の単純なパターンに基づいてフォーマッタを作成します。

そして、これらすべての文字が定義されています。

では、なぜDateTimeFormatter.ofPatternパターン文字を使用できないのでしょうか。

回答:


219

LocalDateDateTimeではなく、日付のみを表します。したがって、「HH:mm:ss」はをフォーマットするときに意味がありませんLocalDateLocalDateTime日付と時刻の両方を表す場合は、代わりにを使用してください。


3
どのように私はこの答えをupvoteとLOCALDATEとのLocalDateTimeオブジェクトの両方が...そこにある事実をdownvoteすることができます
Xials

私はLocalTimeだけで作業したいと思います。この例外にjava.time.temporal.UnsupportedTemporalTypeException: Unsupported field: DayOfWeek
遭遇

気にしないでください:これは機能しますDateTimeFormatter.ofPattern("HH:mm:ss")
サミュエルオウィノ

36

@James_Dの正解に次の詳細を追加したいと思います。

背景:ほとんどの日付と時刻のライブラリ(java.util.CalendarJavaでは、.Net-DateTimeまたはDateJavaScriptまたはDateTimePerl でも参照)は、万能で汎用的な一意の時間型の概念に基づいています(ドイツ語では詩的な表現があります) eierlegende Wollmilchsau」)。この設計では、サポートされていないフィールドは存在できません。しかし、価格は高くなります。多くの時間の問題は、あらゆる種類の時間オブジェクトに共通する特徴を見つけるのが難しいため、このような柔軟性のないアプローチでは適切に処理できません。

JSR-310は別の方法を選択しました。つまり、サポートされている組み込みフィールドのタイプ固有のセットで構成されるさまざまな時間タイプを許可します。自然な結果として、すべての可能なフィールドがすべてのタイプでサポートされるわけではありません(ユーザーは独自の専門フィールドを定義することもできます)。プログラムで、型のすべてのオブジェクトにTemporalAccessor、サポートされているフィールドの特定のセットを要求することもできます。以下のためのLocalDate私たちが見つけます:

DAY_OF_WEEK 
ALIGNED_DAY_OF_WEEK_IN_MONTH 
ALIGNED_DAY_OF_WEEK_IN_YEAR 
DAY_OF_MONTH 
DAY_OF_YEAR 
EPOCH_DAY 
ALIGNED_WEEK_OF_MONTH 
ALIGNED_WEEK_OF_YEAR 
MONTH_OF_YEAR 
PROLEPTIC_MONTH 
YEAR_OF_ERA 
YEAR 
ERA 

の問題を説明するHOUR_OF_DAYフィールドはありませんUnsupportedTemporalTypeException。また、パターンシンボルのフィールドへの JSR-310- マッピングを見ると、シンボルHがサポートされていないHOUR_OF_DAYにマッピングされていることがわかります。

/** Map of letters to fields. */  
private static final Map<Character, TemporalField> FIELD_MAP = new HashMap<>();
static {
  FIELD_MAP.put('G', ChronoField.ERA);
  FIELD_MAP.put('y', ChronoField.YEAR_OF_ERA);
  FIELD_MAP.put('u', ChronoField.YEAR);
  FIELD_MAP.put('Q', IsoFields.QUARTER_OF_YEAR);
  FIELD_MAP.put('q', IsoFields.QUARTER_OF_YEAR);
  FIELD_MAP.put('M', ChronoField.MONTH_OF_YEAR);
  FIELD_MAP.put('L', ChronoField.MONTH_OF_YEAR);
  FIELD_MAP.put('D', ChronoField.DAY_OF_YEAR);
  FIELD_MAP.put('d', ChronoField.DAY_OF_MONTH);
  FIELD_MAP.put('F', ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH);
  FIELD_MAP.put('E', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('c', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('e', ChronoField.DAY_OF_WEEK);
  FIELD_MAP.put('a', ChronoField.AMPM_OF_DAY);
  FIELD_MAP.put('H', ChronoField.HOUR_OF_DAY);
  FIELD_MAP.put('k', ChronoField.CLOCK_HOUR_OF_DAY);
  FIELD_MAP.put('K', ChronoField.HOUR_OF_AMPM);
  FIELD_MAP.put('h', ChronoField.CLOCK_HOUR_OF_AMPM);
  FIELD_MAP.put('m', ChronoField.MINUTE_OF_HOUR);
  FIELD_MAP.put('s', ChronoField.SECOND_OF_MINUTE);
  FIELD_MAP.put('S', ChronoField.NANO_OF_SECOND);
  FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY);
  FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND);
  FIELD_MAP.put('N', ChronoField.NANO_OF_DAY);    
}

このフィールドのマッピングは、フィールドが具象型でサポートされていることを意味するものではありません。解析はいくつかのステップで行われます。フィールドのマッピングは、最初のステップにすぎません。次に、2番目のステップは、タイプのrawオブジェクトへの解析TemporalAccessorです。そして最後に、デリゲートをターゲットタイプ(ここLocalDateでは:)に解析し、解析された中間オブジェクトのすべてのフィールド値を受け入れるかどうかを判断させます。


4
en.wiktionary.org/wiki/eierlegende_Wollmilchsau(文字通り「卵を産むウール-ミルク- ソウ」)肯定的な属性のみを持ち(持っていると主張している)、できる(またはしようとする)オールインワンのデバイスまたは人いくつかの専用ツールの作業を行います。:-)
Trevor Robinson

6

ZonedDateTime時間とタイムゾーンの両方を含む私にとって正しいクラスでした。

LocalDate時間情報がないため、を取得しUnsupportedTemporalTypeException: Unsupported field: HourOfDayます。

使用できますLocalDateTimeが、タイムゾーン情報を持っていないので、それにアクセスしようとすると(事前定義されたフォーマッタの1つを使用しても)、が表示されますUnsupportedTemporalTypeException: Unsupported field: OffsetSeconds

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.