import { getProperties } from "@ember/object"; /* DateWithZoneHelper provides a limited list of helpers to manipulate a moment object with timezones - add(count unit) adds a COUNT of UNITS to a date - subtract(count unit) subtracts a COUNT of UNITS to a date - format(format) formats a date with zone in a consistent way, optional moment format - 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 - unitRepetitionsBetweenDates(duration, date) return the number of repetitions of duration between two dates, eg for duration: "1.weeks", "2.months"... */ export default class DateWithZoneHelper { static fromDatetime(datetime, timezone, localTimezone) { return new DateWithZoneHelper({ year: datetime.year(), month: datetime.month(), day: datetime.date(), hour: datetime.hour(), minute: datetime.minute(), second: datetime.second(), timezone, localTimezone, }); } constructor(params = {}) { this.timezone = params.timezone || "UTC"; this.localTimezone = params.localTimezone || moment.tz.guess(); this.datetime = moment.tz( getProperties(params, [ "year", "month", "day", "hour", "minute", "second", ]), this.timezone ); } isDST() { return this.datetime.tz(this.localTimezone).isDST(); } unitRepetitionsBetweenDates(duration, date) { const [count, unit] = duration.split("."); // 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) { return this._fromDatetime( this.datetime.clone().add(count, unit), this.timezone, this.localTimezone ); } subtract(count, unit) { return this._fromDatetime( this.datetime.clone().subtract(count, unit), this.timezone, this.localTimezone ); } datetimeWithZone(timezone) { return this.datetime.clone().tz(timezone); } format(format) { if (format) { return this.datetime.tz(this.localTimezone).format(format); } return this.datetime.tz(this.localTimezone).toISOString(true); } _fromDatetime(datetime, timezone, localTimezone) { return DateWithZoneHelper.fromDatetime(datetime, timezone, localTimezone); } }