Skip to content

Commit

Permalink
Add fromDurationLike method (moment#1062)
Browse files Browse the repository at this point in the history
* add fromDurationLike method

* fix(test): remove expect.assertions
  • Loading branch information
nazarvovk authored Nov 5, 2021
1 parent 5bd6c37 commit 3eb2806
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 26 deletions.
6 changes: 3 additions & 3 deletions src/datetime.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Duration, { friendlyDuration } from "./duration.js";
import Duration from "./duration.js";
import Interval from "./interval.js";
import Settings from "./settings.js";
import Info from "./info.js";
Expand Down Expand Up @@ -1382,7 +1382,7 @@ export default class DateTime {
*/
plus(duration) {
if (!this.isValid) return this;
const dur = friendlyDuration(duration);
const dur = Duration.fromDurationLike(duration);
return clone(this, adjustTime(this, dur));
}

Expand All @@ -1394,7 +1394,7 @@ export default class DateTime {
*/
minus(duration) {
if (!this.isValid) return this;
const dur = friendlyDuration(duration).negate();
const dur = Duration.fromDurationLike(duration).negate();
return clone(this, adjustTime(this, dur));
}

Expand Down
45 changes: 26 additions & 19 deletions src/duration.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,30 @@ export default class Duration {
});
}

/**
* Create a Duration from DurationLike.
*
* @param {Object | number | Duration} durationLike
* One of:
* - object with keys like 'years' and 'hours'.
* - number representing milliseconds
* - Duration instance
* @return {Duration}
*/
static fromDurationLike(durationLike) {
if (isNumber(durationLike)) {
return Duration.fromMillis(durationLike);
} else if (Duration.isDuration(durationLike)) {
return durationLike;
} else if (typeof durationLike === "object") {
return Duration.fromObject(durationLike);
} else {
throw new InvalidArgumentError(
`Unknown duration argument ${durationLike} of type ${typeof durationLike}`
);
}
}

/**
* Create a Duration from an ISO 8601 duration string.
* @param {string} text - text to parse
Expand Down Expand Up @@ -532,7 +556,7 @@ export default class Duration {
plus(duration) {
if (!this.isValid) return this;

const dur = friendlyDuration(duration),
const dur = Duration.fromDurationLike(duration),
result = {};

for (const k of orderedUnits) {
Expand All @@ -552,7 +576,7 @@ export default class Duration {
minus(duration) {
if (!this.isValid) return this;

const dur = friendlyDuration(duration);
const dur = Duration.fromDurationLike(duration);
return this.plus(dur.negate());
}

Expand Down Expand Up @@ -843,20 +867,3 @@ export default class Duration {
return true;
}
}

/**
* @private
*/
export function friendlyDuration(durationish) {
if (isNumber(durationish)) {
return Duration.fromMillis(durationish);
} else if (Duration.isDuration(durationish)) {
return durationish;
} else if (typeof durationish === "object") {
return Duration.fromObject(durationish);
} else {
throw new InvalidArgumentError(
`Unknown duration argument ${durationish} of type ${typeof durationish}`
);
}
}
8 changes: 4 additions & 4 deletions src/interval.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import DateTime, { friendlyDateTime } from "./datetime.js";
import Duration, { friendlyDuration } from "./duration.js";
import Duration from "./duration.js";
import Settings from "./settings.js";
import { InvalidArgumentError, InvalidIntervalError } from "./errors.js";
import Invalid from "./impl/invalid.js";
Expand Down Expand Up @@ -106,7 +106,7 @@ export default class Interval {
* @return {Interval}
*/
static after(start, duration) {
const dur = friendlyDuration(duration),
const dur = Duration.fromDurationLike(duration),
dt = friendlyDateTime(start);
return Interval.fromDateTimes(dt, dt.plus(dur));
}
Expand All @@ -118,7 +118,7 @@ export default class Interval {
* @return {Interval}
*/
static before(end, duration) {
const dur = friendlyDuration(duration),
const dur = Duration.fromDurationLike(duration),
dt = friendlyDateTime(end);
return Interval.fromDateTimes(dt.minus(dur), dt);
}
Expand Down Expand Up @@ -333,7 +333,7 @@ export default class Interval {
* @return {Array}
*/
splitBy(duration) {
const dur = friendlyDuration(duration);
const dur = Duration.fromDurationLike(duration);

if (!this.isValid || !dur.isValid || dur.as("milliseconds") === 0) {
return [];
Expand Down
27 changes: 27 additions & 0 deletions test/duration/create.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,30 @@ test("Duration.fromObject is valid if providing options only", () => {
expect(dur.milliseconds).toBe(0);
expect(dur.isValid).toBe(true);
});

//------
// .fromDurationLike()
//-------

it("Duration.fromDurationLike returns a Duration from millis", () => {
const dur = Duration.fromDurationLike(1000);
expect(dur).toBeInstanceOf(Duration);
expect(dur).toMatchInlineSnapshot(`"PT1S"`);
});

it("Duration.fromDurationLike returns a Duration from object", () => {
const dur = Duration.fromDurationLike({ hours: 1 });
expect(dur).toBeInstanceOf(Duration);
expect(dur.toObject()).toStrictEqual({ hours: 1 });
});

it("Duration.fromDurationLike returns passed Duration", () => {
const durFromObject = Duration.fromObject({ hours: 1 });
const dur = Duration.fromDurationLike(durFromObject);
expect(dur).toStrictEqual(durFromObject);
});

it("Duration.fromDurationLike returns passed Duration", () => {
expect(() => Duration.fromDurationLike("foo")).toThrow();
expect(() => Duration.fromDurationLike(null)).toThrow();
});

0 comments on commit 3eb2806

Please sign in to comment.