TL; DR:いいえ、あなたのコードが正しくありません。はい、SimpleDateFormat
の代わりに最新のJavaの日付と時刻APIを使用することをおすすめします。
あなたの最初の問題は、共通の時代(BCE、 "キリストの前")の前の年の正確さを定義することです。
私がWikipediaを読んだとき、ISO 8601はその範囲内の日付の解釈方法を明確に定義していません。その年自体は大きな問題ではありません。「0000年は1 BCEと等しい」ので、-1は2 BCE、-2017はBCE 2018です。 mayは、グレゴリオ暦を1582年の正式な導入に先立って延長して作成された予防的グレゴリオ暦を使用しますが、これは伝統的に使用されているユリウス暦とは異なるので注意してください。歴史書の1月4日と同じ日ではありません。また、負の年の使用とプロポーショナルなグレゴリオ暦は、ISO 8601の要件ではなく、当事者間の合意によってのみ行われます。予約:歴史書にBCEの2018年1月4日の定義があるかどうかはわかりません。私たちはユリウス暦の導入前に戻っています(紀元前46年にジュリアス・カエサルによって提案されました)。
The documentation of SimpleDateFormat
グレゴリオ暦が導入される前の日付の処理方法は記載されていません。これは、日付/時刻フォーマッタに関連付けられたCalendar
オブジェクトに依存するようです。このようなCalendar
オブジェクトはほとんどのコンピュータとJVMではGregorianCalendar
ですが、必ずしもそうとは限りません。だから私はあなたのコードからの出力はすべてのコンピュータで同じであることが保証されていないことを取る。そして、GregorianCalendar
は、通常、ユリウス暦の教皇グレゴール前の日付を扱うことができるので、の結果はは歴史書には同意しますが、ISO 8601には同意しません。 2018年1月4日、BCE。だからこれらの理由で私はあなたの結果が正しいとは思わない。
テストでは、あなたのコードの出力を、Javaの日付と時刻APIの同様の使い方の出力と比較しました。コードを実行すると、-125818806600
も得られます。だから私が試した:
System.out.println(OffsetDateTime.parse("-2017-01-04T12:30:00+05:00")
.toInstant()
.getEpochSecond());
これらのクラスは、ISO 8601に準拠しなければなりませんので、私は(それも少し簡単です)あなたの上にこのコードを好むだろう。私はそれは同じではありませんので、あなたのコードが正しい結果が得られていないことを別の記号
-125817294600
を得ました。差は1512000秒で、17日の12時間と同じです。私が理解していないことを認めて始めましょう。私はすぐにジュリアンとグレゴリオ暦の違いが17日か18日の違いを説明できると思います。しかし12時間は私を混乱させる。
編集:12時間は、フォーマットパターン文字列に小文字のhh
を使用したことに由来します。 AM/PMマーカーがないので、大文字のHH
を使用する必要があります。このエラーを修正、あなたのコードからの出力は、今すぐあなたのコードと私の間の差は1468800秒または正確に17日である
-125818763400
です。
hh
は、1〜12の範囲のAMまたはPM内の時間です。大文字のHH
は、1日中の0〜23です。 SimpleDateFormat
とよくある間違いです(現代のクラスではなく、それをキャッチして修正します)。ほとんどの時間は同じ結果になるので、それは気付かれないことがあります。 SimpleDateFormat
はAMをデフォルトとして使用し、たとえば14:30の解析を行い、午後2:30と理解しています。しかし、文字列の時間が12になるので、12:30 AMはその日の0:30を意味し、ISO 12:30は12:30 PMを意味します。したがって、12時間のエラー。
*否定的な日付*とは何ですか? '-2017-01-04'が有効な日付であるカレンダーはありますか? –
エポックの1年前にしたい場合は、エポックから1年後に作成してください。 –
達成しようとしていることを明確にすることができますか? –