tl; dr
ホストマシンのシステムクロックを手動で変更する以外に、System.currentTimeMillisを介して提示されるように、コードまたはJVM引数を使用して現在時刻を上書きする方法はありますか?
はい。
Instant.now(
Clock.fixed(
Instant.parse( "2016-01-23T12:34:56Z"), ZoneOffset.UTC
)
)
Clock
java.time内
プラグイン可能なクロックの交換の問題に対する新しい解決策があり、偽の日時値でのテストを容易にします。Java 8のjava.timeパッケージには、明確な目的を持つ抽象クラスが含まれていますjava.time.Clock
。
必要に応じて代替クロックを接続できるようにする
独自のの実装をプラグインすることもできClock
ますが、ニーズを満たすためにすでに作成されている実装を見つけることができます。便宜上、java.timeには特別な実装を生成する静的メソッドが含まれています。これらの代替実装は、テスト中に価値があります。
ケイデンスの変更
さまざまな tick…
方法で、現在の瞬間を異なるリズムで増加させる時計が生成されます。
デフォルトでは、Clock
頻繁に更新されて、時間報告ミリ秒として罰金としてのJava 8とJava 9でナノ秒 (ハードウェアに依存します)。実際の現在の瞬間を異なる粒度で報告するように要求できます。
偽時計
一部のクロックは嘘をつき、ホストOSのハードウェアクロックとは異なる結果を生成する可能性があります。
たとえば、今年の最初のクリスマスの最初の瞬間に固定します。つまり、サンタとトナカイが最初に立ち寄ったときです。早い時間帯は、今日のようですPacific/Kiritimati
で+14:00
。
LocalDate ld = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate xmasThisYear = MonthDay.of( Month.DECEMBER , 25 ).atYear( ld.getYear() );
ZoneId earliestXmasZone = ZoneId.of( "Pacific/Kiritimati" ) ;
ZonedDateTime zdtEarliestXmasThisYear = xmasThisYear.atStartOfDay( earliestXmasZone );
Instant instantEarliestXmasThisYear = zdtEarliestXmasThisYear.toInstant();
Clock clockEarliestXmasThisYear = Clock.fixed( instantEarliestXmasThisYear , earliestXmasZone );
その特別な固定クロックを使用して、常に同じ瞬間を返します。私たちは、クリスマスの日の最初の瞬間を取得するクリスマス島 UTCを示すとともに、壁時計時間 12月24日の前の日に14時間前、午前10時のを。
Instant instant = Instant.now( clockEarliestXmasThisYear );
ZonedDateTime zdt = ZonedDateTime.now( clockEarliestXmasThisYear );
instant.toString():2016-12-24T10:00:00Z
zdt.toString():2016-12-25T00:00 + 14:00 [太平洋/キリティマティ]
IdeOne.comのライブコードを参照してください。
実際の時間、異なるタイムゾーン
Clock
実装によって割り当てられるタイムゾーンを制御できます。これは、一部のテストで役立つ場合があります。ただし、これは、常にオプションZoneId
またはZoneOffset
引数を明示的に指定する必要がある本番用コードではお勧めしません。
UTCをデフォルトゾーンとして指定できます。
ZonedDateTime zdtClockSystemUTC = ZonedDateTime.now ( Clock.systemUTC () );
特定のタイムゾーンを指定できます。指定適切なタイムゾーン名をの形式でcontinent/region
、のようなAmerica/Montreal
、Africa/Casablanca
またはPacific/Auckland
。決してなど3-4文字の略称を使用していないEST
か、IST
そのままではない真の時間帯ではなく、標準化、さらには一意ではありません(!)。
ZonedDateTime zdtClockSystem = ZonedDateTime.now ( Clock.system ( ZoneId.of ( "America/Montreal" ) ) );
JVMの現在のデフォルトのタイムゾーンを特定のClock
オブジェクトのデフォルトにする必要があることを指定できます。
ZonedDateTime zdtClockSystemDefaultZone = ZonedDateTime.now ( Clock.systemDefaultZone () );
このコードを実行して比較します。それらはすべて同じ瞬間、タイムライン上の同じポイントを報告することに注意してください。それらは壁時計時間のみが異なります。つまり、同じことを言う3つの方法、同じ瞬間を表示する3つの方法です。
System.out.println ( "zdtClockSystemUTC.toString(): " + zdtClockSystemUTC );
System.out.println ( "zdtClockSystem.toString(): " + zdtClockSystem );
System.out.println ( "zdtClockSystemDefaultZone.toString(): " + zdtClockSystemDefaultZone );
America/Los_Angeles
このコードを実行したコンピューター上のJVMの現在のデフォルトゾーンでした。
zdtClockSystemUTC.toString():2016-12-31T20:52:39.688Z
zdtClockSystem.toString():2016-12-31T15:52:39.750-05:00 [アメリカ/モントリオール]
zdtClockSystemDefaultZone.toString():2016-12-31T12:52:39.762-08:00 [America / Los_Angeles]
Instant
クラスが定義によってUTCに常にあります。したがって、これらの3つのゾーン関連のClock
使用法はまったく同じ効果があります。
Instant instantClockSystemUTC = Instant.now ( Clock.systemUTC () );
Instant instantClockSystem = Instant.now ( Clock.system ( ZoneId.of ( "America/Montreal" ) ) );
Instant instantClockSystemDefaultZone = Instant.now ( Clock.systemDefaultZone () );
instantClockSystemUTC.toString():2016-12-31T20:52:39.763Z
instantClockSystem.toString():2016-12-31T20:52:39.763Z
instantClockSystemDefaultZone.toString():2016-12-31T20:52:39.763Z
デフォルトの時計
のデフォルトで使用される実装Instant.now
は、によって返されるものClock.systemUTC()
です。これは、を指定しない場合に使用される実装ですClock
。のプレリリースJava 9ソースコードをご確認くださいInstant.now
。
public static Instant now() {
return Clock.systemUTC().instant();
}
デフォルトClock
用OffsetDateTime.now
とZonedDateTime.now
ですClock.systemDefaultZone()
。ソースコードを参照してください。
public static ZonedDateTime now() {
return now(Clock.systemDefaultZone());
}
Java 8とJava 9の間でデフォルト実装の動作が変更されました。Java8では、ナノ秒の分解能を格納するクラスの機能にもかかわらず、現在の瞬間はミリ秒単位の分解能でキャプチャされます。Java 9は、ナノ秒の分解能で現在の瞬間をキャプチャできる新しい実装をもたらします。もちろん、コンピューターのハードウェアクロックの機能によって異なります。
java.timeについて
java.timeのフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスをjava.util.Date
、Calendar
、& SimpleDateFormat
。
ジョダタイムプロジェクトは、今でメンテナンスモードへの移行をアドバイスjava.timeのクラス。
詳細については、Oracleチュートリアルを参照してください。スタックオーバーフローで多くの例と説明を検索してください。仕様はJSR 310です。
java.timeオブジェクトをデータベースと直接交換することができます。JDBC 4.2以降に準拠したJDBCドライバーを使用します。文字列もクラスも必要ありません。java.sql.*
java.timeクラスはどこで入手できますか?
ThreeTen-エクストラプロジェクトでは、追加のクラスでjava.timeを拡張します。このプロジェクトは、java.timeに将来追加される可能性があることを証明する場です。あなたはここにいくつかの有用なクラスのような見つけることがInterval
、YearWeek
、YearQuarter
、および多くを。