From fc6df79b6582407afe9f1d0762774bc7ea63b239 Mon Sep 17 00:00:00 2001 From: henryw374 Date: Thu, 12 Jul 2018 07:44:52 +0100 Subject: [PATCH] add OffsetClock --- src/Clock.js | 68 +++++++++++++++++++++++++++++++++++++++++++++++ test/ClockTest.js | 13 +++++++++ 2 files changed, 81 insertions(+) diff --git a/src/Clock.js b/src/Clock.js index 57cb36670..dbf96d68c 100644 --- a/src/Clock.js +++ b/src/Clock.js @@ -104,6 +104,29 @@ export class Clock { static fixed(fixedInstant, zoneOffset) { return new FixedClock(fixedInstant, zoneOffset); } + + /** + * Obtains a clock that returns instants from the specified clock with the + * specified duration added + *

+ * This clock wraps another clock, returning instants that are later by the + * specified duration. If the duration is negative, the instants will be + * earlier than the current date and time. + * The main use case for this is to simulate running in the future or in the past. + *

+ * A duration of zero would have no offsetting effect. + * Passing zero will return the underlying clock. + *

+ * The returned implementation is immutable, thread-safe and {@code Serializable} + * providing that the base clock is. + * + * @param baseClock the base clock to add the duration to, not null + * @param offsetDuration the duration to add, not null + * @return a clock based on the base clock with the duration added, not null + */ + static offset(baseClock, duration) { + return new OffsetClock(baseClock, duration); + } /** * Gets the current millisecond instant of the clock. @@ -220,3 +243,48 @@ class FixedClock extends Clock{ return 'FixedClock[]'; } } + + +/** + * Implementation of a clock that adds an offset to an underlying clock. + */ +class OffsetClock extends Clock { + constructor(baseClock, offset) { + super(); + this._baseClock = baseClock; + this._offset = offset; + } + + zone() { + return this._baseClock.zone(); + } + + + withZone(zone) { + if (zone.equals(this._baseClock.zone())) { // intentional NPE + return this; + } + return new OffsetClock(this._baseClock.withZone(zone), this._offset); + } + + millis() { + return this._baseClock.millis() + this._offset.toMillis(); + } + + instant() { + return this._baseClock.instant().plus(this._offset); + } + + + equals(obj) { + if (obj instanceof OffsetClock) { + + return this._baseClock.equals(obj.baseClock) && this._offset.equals(obj.offset); + } + return false; + } + + toString() { + return 'OffsetClock[' + this._baseClock + ',' + this._offset + ']'; + } +} \ No newline at end of file diff --git a/test/ClockTest.js b/test/ClockTest.js index c7fa6df43..86b16af70 100644 --- a/test/ClockTest.js +++ b/test/ClockTest.js @@ -7,6 +7,9 @@ import {expect} from 'chai'; import './_init'; import {Clock} from '../src/Clock'; +import {Duration} from '../src/Duration'; +import {Instant} from '../src/Instant'; +import {ZoneId} from '../src/ZoneId'; describe('Clock', () => { describe('should deny calling an instant method of pseudo abstract class Clock', () => { @@ -38,5 +41,15 @@ describe('Clock', () => { expect(Clock.fixed().toString()).to.contain('FixedClock'); }); }); + + describe('offset clock', () => { + it('is offset', () => { + const duration = Duration.parse('PT0H3M'); + const base = Clock.fixed(Instant.now(), ZoneId.systemDefault()); + const offset = Clock.offset(base, duration); + expect(base.millis() === offset.millis() + duration.toMillis()); + }); + + }); });