/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Portions Copyright (C) Philipp Kewisch */ import { strictParseInt, trunc, pad2 } from "./helpers.js"; // needed for typescript type resolution // eslint-disable-next-line no-unused-vars import Duration from "./duration.js"; import design from "./design.js"; /** * This class represents the "utc-offset" value type, with various calculation and manipulation * methods. * * @memberof ICAL */ class UtcOffset { /** * Creates a new {@link ICAL.UtcOffset} instance from the passed string. * * @param {String} aString The string to parse * @return {Duration} The created utc-offset instance */ static fromString(aString) { // -05:00 let options = {}; //TODO: support seconds per rfc5545 ? options.factor = (aString[0] === '+') ? 1 : -1; options.hours = strictParseInt(aString.slice(1, 3)); options.minutes = strictParseInt(aString.slice(4, 6)); return new UtcOffset(options); } /** * Creates a new {@link ICAL.UtcOffset} instance from the passed seconds * value. * * @param {Number} aSeconds The number of seconds to convert */ static fromSeconds(aSeconds) { let instance = new UtcOffset(); instance.fromSeconds(aSeconds); return instance; } /** * Creates a new ICAL.UtcOffset instance. * * @param {Object} aData An object with members of the utc offset * @param {Number=} aData.hours The hours for the utc offset * @param {Number=} aData.minutes The minutes in the utc offset * @param {Number=} aData.factor The factor for the utc-offset, either -1 or 1 */ constructor(aData) { this.fromData(aData); } /** * The hours in the utc-offset * @type {Number} */ hours = 0; /** * The minutes in the utc-offset * @type {Number} */ minutes = 0; /** * The sign of the utc offset, 1 for positive offset, -1 for negative * offsets. * @type {Number} */ factor = 1; /** * The type name, to be used in the jCal object. * @constant * @type {String} * @default "utc-offset" */ icaltype = "utc-offset"; /** * Returns a clone of the utc offset object. * * @return {UtcOffset} The cloned object */ clone() { return UtcOffset.fromSeconds(this.toSeconds()); } /** * Sets up the current instance using members from the passed data object. * * @param {Object} aData An object with members of the utc offset * @param {Number=} aData.hours The hours for the utc offset * @param {Number=} aData.minutes The minutes in the utc offset * @param {Number=} aData.factor The factor for the utc-offset, either -1 or 1 */ fromData(aData) { if (aData) { for (let [key, value] of Object.entries(aData)) { this[key] = value; } } this._normalize(); } /** * Sets up the current instance from the given seconds value. The seconds * value is truncated to the minute. Offsets are wrapped when the world * ends, the hour after UTC+14:00 is UTC-12:00. * * @param {Number} aSeconds The seconds to convert into an offset */ fromSeconds(aSeconds) { let secs = Math.abs(aSeconds); this.factor = aSeconds < 0 ? -1 : 1; this.hours = trunc(secs / 3600); secs -= (this.hours * 3600); this.minutes = trunc(secs / 60); return this; } /** * Convert the current offset to a value in seconds * * @return {Number} The offset in seconds */ toSeconds() { return this.factor * (60 * this.minutes + 3600 * this.hours); } /** * Compare this utc offset with another one. * * @param {UtcOffset} other The other offset to compare with * @return {Number} -1, 0 or 1 for less/equal/greater */ compare(other) { let a = this.toSeconds(); let b = other.toSeconds(); return (a > b) - (b > a); } _normalize() { // Range: 97200 seconds (with 1 hour inbetween) let secs = this.toSeconds(); let factor = this.factor; while (secs < -43200) { // = UTC-12:00 secs += 97200; } while (secs > 50400) { // = UTC+14:00 secs -= 97200; } this.fromSeconds(secs); // Avoid changing the factor when on zero seconds if (secs == 0) { this.factor = factor; } } /** * The iCalendar string representation of this utc-offset. * @return {String} */ toICALString() { return design.icalendar.value['utc-offset'].toICAL(this.toString()); } /** * The string representation of this utc-offset. * @return {String} */ toString() { return (this.factor == 1 ? "+" : "-") + pad2(this.hours) + ':' + pad2(this.minutes); } } export default UtcOffset;