diff --git a/plugins/discourse-local-dates/assets/javascripts/lib/date-with-zone-helper.js.es6 b/plugins/discourse-local-dates/assets/javascripts/lib/date-with-zone-helper.js.es6 index eacbcba47f1..d82cfa4d0d4 100644 --- a/plugins/discourse-local-dates/assets/javascripts/lib/date-with-zone-helper.js.es6 +++ b/plugins/discourse-local-dates/assets/javascripts/lib/date-with-zone-helper.js.es6 @@ -10,7 +10,7 @@ const { getProperties } = Ember; - isDST() allows to know if a date in a specified timezone is currently under DST - datetimeWithZone(timezone) returns a new moment object with timezone applied - datetime returns the moment object - - repetitionsBetweenDates(duration, date) return the number of repertitions of + - unitRepetitionsBetweenDates(duration, date) return the number of repertitions of duration between two dates, eg for duration: "1.weeks", "2.months"... */ export default class DateWithZoneHelper { @@ -35,11 +35,18 @@ export default class DateWithZoneHelper { return this.datetime.tz(this.localTimezone).isDST(); } - repetitionsBetweenDates(duration, date) { + unitRepetitionsBetweenDates(duration, date) { const [count, unit] = duration.split("."); - const diff = this.datetime.diff(date, unit); - const repetitions = diff / parseInt(count, 10); - return Math.abs((Math.round(repetitions * 10) / 10).toFixed(1)); + // get the diff in the specified units with decimals + const diff = Math.abs(this.datetime.diff(date, unit, true)); + // get integer count of duration in diff, eg: 4 hours diff is 2 for 2.hours duration + const integer = Math.trunc(diff / count); + // get fractional to define if we have to add one "duration" + const fractional = (diff / count) % 1; + + return ( + integer * parseInt(count, 10) + (fractional > 0 ? parseInt(count, 10) : 0) + ); } add(count, unit) { diff --git a/plugins/discourse-local-dates/assets/javascripts/lib/local-date-builder.js.es6 b/plugins/discourse-local-dates/assets/javascripts/lib/local-date-builder.js.es6 index 123c6150f31..915d87ccf64 100644 --- a/plugins/discourse-local-dates/assets/javascripts/lib/local-date-builder.js.es6 +++ b/plugins/discourse-local-dates/assets/javascripts/lib/local-date-builder.js.es6 @@ -48,14 +48,14 @@ export default class LocalDateBuilder { }); if (this.recurring && moment().isAfter(localDate.datetime)) { - const [count, type] = this.recurring.split("."); + const type = this.recurring.split(".")[1]; - const repetitionsForType = localDate.repetitionsBetweenDates( + const repetitionsForType = localDate.unitRepetitionsBetweenDates( this.recurring, moment.tz(this.localTimezone) ); - localDate = localDate.add(repetitionsForType + parseInt(count, 10), type); + localDate = localDate.add(repetitionsForType, type); } const previews = this._generatePreviews(localDate, displayedTimezone); diff --git a/plugins/discourse-local-dates/test/javascripts/lib/date-with-zone-helper-test.js.es6 b/plugins/discourse-local-dates/test/javascripts/lib/date-with-zone-helper-test.js.es6 index db8ea4b1c71..af43d091f1f 100644 --- a/plugins/discourse-local-dates/test/javascripts/lib/date-with-zone-helper-test.js.es6 +++ b/plugins/discourse-local-dates/test/javascripts/lib/date-with-zone-helper-test.js.es6 @@ -28,7 +28,7 @@ test("#format", function (assert) { assert.equal(date.format(), "2020-03-15T15:36:00.000+01:00"); }); -test("#repetitionsBetweenDates", function (assert) { +test("#unitRepetitionsBetweenDates", function (assert) { let date; date = buildDateHelper({ @@ -39,7 +39,7 @@ test("#repetitionsBetweenDates", function (assert) { timezone: PARIS, }); assert.equal( - date.repetitionsBetweenDates( + date.unitRepetitionsBetweenDates( "1.hour", moment.tz("2020-02-15 15:36", SYDNEY) ), @@ -55,7 +55,7 @@ test("#repetitionsBetweenDates", function (assert) { timezone: PARIS, }); assert.equal( - date.repetitionsBetweenDates( + date.unitRepetitionsBetweenDates( "1.minute", moment.tz("2020-02-15 15:36", PARIS) ), @@ -71,7 +71,7 @@ test("#repetitionsBetweenDates", function (assert) { timezone: PARIS, }); assert.equal( - date.repetitionsBetweenDates( + date.unitRepetitionsBetweenDates( "1.minute", moment.tz("2020-02-15 15:37", PARIS) ), @@ -87,11 +87,11 @@ test("#repetitionsBetweenDates", function (assert) { timezone: PARIS, }); assert.equal( - date.repetitionsBetweenDates( - "2.minute", + date.unitRepetitionsBetweenDates( + "2.minutes", moment.tz("2020-02-15 15:41", PARIS) ), - 2.5, + 6, "it correctly finds difference with a multiplicator" ); }); diff --git a/plugins/discourse-local-dates/test/javascripts/lib/local-date-builder-test.js.es6 b/plugins/discourse-local-dates/test/javascripts/lib/local-date-builder-test.js.es6 index 06b29e0e269..74fb2907d61 100644 --- a/plugins/discourse-local-dates/test/javascripts/lib/local-date-builder-test.js.es6 +++ b/plugins/discourse-local-dates/test/javascripts/lib/local-date-builder-test.js.es6 @@ -233,6 +233,21 @@ test("option[recurring]", function (assert) { "it works for a future date" ); }); + + freezeTime({ date: "2021-01-08 11:16" }, () => { + assert.buildsCorrectDate( + { + date: "2021-01-05", + time: "14:00", + recurring: "2.hours", + timezone: NEW_YORK, + }, + { + formated: "Today 12:00 PM", + }, + "it works with hours" + ); + }); }); test("option[countown]", function (assert) {