DateTimeFormatter
クラスのドキュメントには、その年のフォーマットコードについて記載されています。
u年2004年; 04
y 2004年の年。 04
…
年:文字の数は、それ以下でパディングが使用される最小フィールド幅を決定します。文字数が2の場合、2桁の短縮形が使用されます。印刷の場合、これは右端の2桁を出力します。解析の場合、これは2000のベース値を使用して解析し、2000〜2099の範囲内の年になります。文字数が4未満(2ではない)の場合、SignStyle.NORMALに従って負の年の記号のみが出力されます。それ以外の場合、SignStyle.EXCEEDS_PADに従って、パッド幅を超えると符号が出力されます。
「時代」に関する他の言及はありません。
これら2つのコードの違いは何ですか、u
対y
、year
対year-of-era
?
いつこのパターンのようなものを使うべきですかuuuu-MM-dd
およびyyyy-MM-dd
Javaで日付を扱うときは?
知識のある人によって書かれたサンプルコードはuuuu
を使用しているようですが、なぜですか?
従来の SimpleDateFormat
などの他のフォーマットクラスにはyyyy
しかありません。そのため、Java.timeがuuuu
を「時代の年」にもたらす理由を混乱させています」。
Javadocセクション フォーマットと解析のパターン のDateTimeFormatter
には、次の3つの関連するシンボルがリストされています。
Symbol Meaning Presentation Examples
------ ------- ------------ -------
G era text AD; Anno Domini; A
u year year 2004; 04
y year-of-era year 2004; 04
比較のために、これらの他の記号は理解するのに十分簡単です:
D day-of-year number 189
d day-of-month number 10
E day-of-week text Tue; Tuesday; T
day-of-year
、day-of-month
、およびday-of-week
は、特定のスコープ(年、月、週)内のdayであることは明らかです。
したがって、year-of-era
は、指定されたスコープ(時代)内のyearを意味し、そのすぐ上にera
がAD
の例の値と共に表示されます(もちろん、BC
である他の値) 。
year
はsigned年です。ここで、年0
は1 BC
、年-1
は2 BC
などです。
例として: Julius Caesar暗殺 ?
MMMM d, y GG
を使用)MMMM d, u
を使用)もちろん、区別は年がゼロまたは負の場合にのみ重要であり、それはまれであるため、ほとんどの人はそうであっても気にしません。
結論:y
を使用する場合は、G
も使用する必要があります。 G
はめったに使用されないため、正しい年記号はu
ではなくy
です。そうでない場合、正でない年は正しく表示されません。
これは defensive programming として知られています:
防御的プログラミングは、ソフトウェアの一部の継続的な機能を保証する予期しない状況の下でを目的とした防御設計の形式です。
DateTimeFormatter
は SimpleDateFormat
と一貫していることに注意してください。
Letter Date or Time Component Presentation Examples
------ ---------------------- ------------ --------
G Era designator Text AD
y Year Year 1996; 96
負の年は常に問題でしたが、彼らはu
を追加することでそれを修正しました。
yyyy
を使用するか、uuuu
を使用するか(または、2桁の年にyy
またはuu
を使用するか)違いはありません。u
とy
がどのように機能するかについては、他に2つの回答がすでにありますが、まだ何かが足りないと感じたので、少し意見に基づいた回答を投稿しています。
1 CEの1年前にフォーマットされることを想定していない場合、できる最善の方法は、この仮定を確認し、破損した場合に適切に対応することです。たとえば、状況と要件に応じて、エラーメッセージを出力したり、例外をスローしたりできます。非常にソフトな障害パスの1つは、この場合はy
(元年)およびG
(元号)のパターンを使用し、通常の現在の元号の場合はu
またはy
のパターンを使用することです。現在の日付またはプログラムがコンパイルされた日付を印刷する場合、それが共通の時代にあることを確認でき、チェックをスキップすることを選択できることに注意してください。
多くの場合(ほとんどの場合)、解析は検証を意味します。つまり、入力文字列がどのように見えるかを保証しません。通常、ユーザーまたは別のシステムから取得されます。例:日付文字列は2018-09-29になります。ここで、uuuu
とyyyy
の間の選択は、文字列に0または負の年が含まれている場合(たとえば、0000-08-17
または-012-11-13
)。これがエラーであると仮定すると、即時の答えは次のとおりです。この場合、例外をスローするにはyyyy
を使用します。さらに細かい:uuuu
を使用し、解析後に解析された日付の範囲チェックを実行します。後者のアプローチでは、検証エラーが発生した場合に、より詳細な検証とより良いエラーメッセージの両方が可能になります。
特別な場合(Meno Hochschildが既に言及):フォーマッターが厳密なリゾルバースタイルを使用し、y
を含まないG
を含む場合、厳密に言えば時代の年はあいまいであるため、解析はalways失敗します:1950は1950 CEを意味する可能性がありますまたは1950 BCE(1950 BC)。したがって、この場合はu
が必要です(またはデフォルトの元号を指定すると、これはDateTimeFormatterBuilder
を介して可能になります)。
日付、特に年の明示的な範囲チェックは、予期しない非常に早い年をキャッチするためにuuuu
とyyyy
の選択に依存するよりも優れています。