Java 8 java.timeクラスにgetMillis()メソッドがないのはなぜですか?


64

Java 8には、パッケージjava.timeに日付と時刻のまったく新しいライブラリがあります。これは、以前にJodaTimeを使用したり、独自の日付処理ヘルパーメソッドを作成したりする必要があるユーザーにとって非常に歓迎されるものです。このパッケージの多くのクラスはタイムスタンプを表し、タイムスタンプgetHour()から時間getMinute()を取得する、タイムスタンプから分を取得する、タイムスタンプからナノを取得するなどのヘルパーメソッドを持っていgetNano()ます...

getMillis()タイムスタンプのミリ秒を取得するために呼び出されるメソッドがないことに気付きました。代わりに、methodを呼び出す必要がありますget(ChronoField.MILLI_OF_SECOND)。私には、図書館の矛盾のように思えます。そのようなメソッドが欠落している理由を誰かが知っていますか、またはJava 8がまだ開発中であるため、後で追加される可能性がありますか?

https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html

ここで定義されているクラスは、インスタント、期間、日付、時刻、タイムゾーン、期間など、主要な日時の概念を表しています。これらはISOカレンダーシステムに基づいています。これは、予言的なグレゴリオ暦のルールに基づいた事実上の世界カレンダーです。すべてのクラスは不変であり、スレッドセーフです。

各日時インスタンスは、APIによって便利に利用できるようになっているフィールドで構成されています。フィールドへの低レベルのアクセスについては、java.time.temporalパッケージを参照してください。各クラスには、あらゆる種類の日付と時刻の印刷と解析のサポートが含まれています。java.time.formatカスタマイズオプションについては、パッケージを参照してください...

この種類のクラスの例:https :
//docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html

2007-12-03T10:15:30など、ISO-8601カレンダーシステムのタイムゾーンのない日時。

LocalDateTimeは、日時を表す不変の日時オブジェクトであり、多くの場合、年月日日時分秒として表示されます。年間通算日、曜日、通年など、他の日付および時刻フィールドにもアクセスできます。時間はナノ秒の精度で表されます。たとえば、「2007年10月2日13:45.30.123456789」という値は、LocalDateTime...


ポリモーフィズムを使用get()して、個別の一意の名前を付けるのではなく、すべて呼び出された一連のメソッドを解決したいようです。気になる場合は、元のクラスを継承するクラスを作成getMillis()し、新しいクラスに独自のメソッドを配置します。
ロバートハーヴェイ14年

@RobertHarvey java.timeパッケージのほとんどのクラスは不変であり、拡張できません。
assylias

2
@RobertHarvey私にとっての質問は、これをどのように解決できるかではありません。それは奇妙な矛盾を継ぎ合わせただけであり、これについて興味深い説明があるのだろうかと思いました。
タルモ

一部のアーキテクチャ/ OSはミリ秒を確実にサポートしていないという考えがあります。つまり、システム時間はミリ秒単位ではなく、センチ秒単位またはデシ秒単位でしか取得できません。
マルコ14年

参照stackoverflow.com/a/23945792/40064を介して、それを行うための方法でInstantクラス
ヴィムDeblauwe

回答:


63

JSR-310は、ミリ秒ではなくナノ秒に基づいています。そのため、賢明なメソッドの最小セットは、時間、分、秒、ナノ秒に基づいています。ナノ秒ベースを持つという決定は、プロジェクトの最初の決定の1つであり、正しいと強く信じています。

ミリ秒のメソッドを追加すると、ナノ秒のメソッドと重複しますが、これは明らかではありません。ユーザーは、例えばナノフィールドがナノ秒かナノミリかを考えなければなりません。混乱を招く追加メソッドを追加することは望ましくないため、このメソッドは省略されました。指摘したように、代替手段get(MILLI_OF_SECOND)が利用可能です。

FWIW、私はgetMillis()将来メソッドを追加することに反対します。


1
私はこの質問に対して非常に良い答えをいくつか得ましたが、あなたの答えは短いので私のお気に入りです。ありがとうございました。
タルモ14

12
@ s3ib answerer のプロファイルをチェックすると、あなたが尋ねているまさにそのAPIの仕様リードであることに気付くでしょう。これは、それが得られないのと同じように信頼できる答えを作ります:)
gnat 14

したがってinstant.getEpochSecond * 1000 + instant.getNano / 1000000、従来の(この時点ではすべての)Java API、Javascriptなどと通信できるようにするための合理的なボイラープレートは必要ですか?
nilskp 14年

10
いいえ、その場合は、
instant.toEpochMilli

20

openJDKに参加する前は、threetenはgithubにあり、それ以前はsourceforgeにありました。当時、jsr-310の仕様リードであるStephen Colebourneは、sourceforgeサイトで引き続き調査できるアンケートを作成しました。

The fourth question on the survey covered the method names for LocalTime:
1) getHourOfDay(), getMinuteOfHour(), getSecondOfMinute(), getNanoOfSecond()
2) getHour(), getMinute(), getSecond(), getNanoOfSecond()
3) getHour(), getMinute(), getSecond(), getNano()
4) another idea

回答#4を選択したのは6.23%のみで、そのうち約15%がaを求めましたgetMillis()。つまり、総投票数の1%未満です。

それがおそらくgetMillisそもそも何もなかった理由であり、openjdkメーリングリストで関連するものを見つけることができなかったので、問題はその後議論されなかったようです。


3
人々にいくつかの選択肢を与えることは、たとえ彼らの理想的な選択肢が「その他」の下にあるとしても、それらの選択肢の1つを選ぶ可能性が高くなると思います。しかし、私は間違っている可能性があります。
アロングラネネク14年

2
@AllonGuralnekはい、間違いなく-ただし、ミリ秒コンポーネントは、すべてがエポック以降のミリ秒に基づいていたため、Date APIでは重要でした。新しいAPIでは、関連性の低いIMOです。ほとんどのユースケースでは、2番目の精度または利用可能な最高の精度(nanos)が必要です。私は間違っているかもしれません。
assylias

1
これは、どのメソッドが存在すべきかではなく、メソッドの命名について尋ねているようです。
svick 14年

1
右、申し訳ありませんが、私は明確ではありませんでした:私は調査からの質問を意味し、それはこの質問に直接関連するものではありません。
svick 14

15

明確なUTC時間(インスタント、OffsetDateTime、ZonedDateTime)を表すクラスには、Javaエポックからの絶対オフセットにアクセスするための2つのヘルパーメソッド、つまりjava.util.Dateで「ミリ秒時間」と呼ばれるものがありますミリ秒で取得する

long getEpochSecond()
int getNano()

1000L*getEpochSecond() + getNano() / 1000000L;

これが代わりに選択された理由に関するいくつかの理由long getEpochMillis()については、、jsr 310メーリングリストでた

ミリ秒の精度では十分ではないと想定するのが妥当と思われます。ただし、ナノ秒の精度を超えるものは過剰に思えます

...

これを実装するための推奨オプションは、64ビット長秒(符号付き)+ 32ビット整数ナノ秒(符号なし)です。

...

科学における公式のSI時間単位であり、最も普遍的に合意された標準であるため、私は分割が第2レベルにあることを好みます。

日レベルでの分割は、うるう秒を処理しないため、インスタントでは問題があります。ミリ秒レベルでの分割は、Javaの他の部分との統合がわずかに優れていますが、かなり奇妙に思えます。さらに、サポートされている範囲内で失われます。

提案されたように秒単位で分割すると、2900億年にわたってナノ秒の範囲の瞬間が得られます。誰もタイムラインのその範囲でその精度を使用するべきではありませんが、それをブロックするよりもサポートする方が簡単であることをお勧めします。日レベルでの分割は、うるう秒を処理しないため、インスタントにとって問題です

開発者が新しいクラスを盲目的に(誤って)使用するだけでなく、さまざまなオプションの違いを理解しようとすることを期待して、意図的にjava.util.DateからJSR310クラスに変換することを困難にすることも別の理由であると感じています。

LocalDateTimeクラスにこれらのメソッドがない理由については、LocalDateTimeあなたがいるゾーンまたはUTCオフセットが何であるかを決定するまでUTCタイムラインに関連付けられていないため、それらが存在しない可能性がありますOffsetDateTimeまたはZonedDateTime(どちらにも必要なメソッドがあります)。

または、独自のLOCAL_EPOCH定数を定義1970-01-01T00:00:00してMILLIS.between(LOCAL_EPOCH, localTime)からa を実行し、ミリ秒単位で何らかの持続時間を取得することもできます。ただし、もちろんローカル時間をUTC時間に定義しない限り、この値はSystem.currentTimeMilliseconds()またはによって返される値と互換性がありませんjava.util.Date.getTime()。ただし、この場合は、Instantを直接使用するか、OffsetDateTimeをZoneOffset.UTCで使用することもできます。


4
LocalDateTimeはUTCタイムラインに関連付けられていないため、おそらく存在しません」=> LocalDateTimeにgetMillisは基本的に返されるメソッドが確実にありgetNanos()/1e6ます。成分。
assylias

2
別の理由は、意図的にjava.util.DateからJSR310クラスへの変換を困難にすることであると感じています。」古いJava API、Javascript、その他と通信するには、この省略は本当に面倒です。
nilskp 14年

上部にあなたのコードスニペットが正しくありません-あなたは1000でgetEpochSecondを乗算する必要がある
ブリキマン

@nilskpこれらは2つの異なるものです。質問はgetMillis()getMillis-of-secondのように尋ねています。あなたは「エポック以来のミリス」について話している。受け入れられた答えで説明されているように、前者はありません。後者はすでにとして利用可能ですInstant.toEpochMillis()。だから、のためにLocalDateTime、あなたは行くだろう:ldt.toInstant(offset).toEpochMillis()
-SusanW
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.