UNPKG

fontoxpath

Version:

A minimalistic XPath 3.1 engine in JavaScript

183 lines (148 loc) 4.2 kB
import AbstractDuration from './AbstractDuration'; import YearMonthDuration from './YearMonthDuration'; import DayTimeDuration from './DayTimeDuration'; const MONTHS_TO_MIN_MAX_VALUES = [ [28, 31], [59, 62], [89, 91], [120, 123], [150, 153], [181, 184], [212, 215], [242, 245], [273, 276], [303, 306], [334, 337], [365, 366] ]; function computeMinDays (duration) { const years = Math.abs(duration.getYears()); const months = Math.abs(duration.getMonths()); const minNumberOfLeapYears = Math.floor(years / 4); return Math.abs(duration.getDays()) + (months === 0 ? 0 : MONTHS_TO_MIN_MAX_VALUES[months - 1][0]) + minNumberOfLeapYears * 366 + (years - minNumberOfLeapYears) * 365; } function computeMaxDays (duration) { const years = Math.abs(duration.getYears()); const months = Math.abs(duration.getMonths()); const maxNumberOfLeapYears = Math.ceil(years / 4); return Math.abs(duration.getDays()) + (months === 0 ? 0 : MONTHS_TO_MIN_MAX_VALUES[months - 1][1]) + maxNumberOfLeapYears * 366 + (years - maxNumberOfLeapYears) * 365; } /** * @extends {AbstractDuration} */ class Duration extends AbstractDuration { constructor (yearMonthDuration, dayTimeDuration) { super(); this._yearMonthDuration = yearMonthDuration; this._dayTimeDuration = dayTimeDuration; } getRawMonths () { return this._yearMonthDuration.getRawMonths(); } getRawSeconds () { return this._dayTimeDuration.getRawSeconds(); } getYearMonthDuration () { return this._yearMonthDuration; } getDayTimeDuration () { return this._dayTimeDuration; } getYears () { return this._yearMonthDuration.getYears(); } getMonths () { return this._yearMonthDuration.getMonths(); } getDays () { return this._dayTimeDuration.getDays(); } getHours () { return this._dayTimeDuration.getHours(); } getMinutes () { return this._dayTimeDuration.getMinutes(); } getSeconds () { return this._dayTimeDuration.getSeconds(); } isPositive () { return this._yearMonthDuration.isPositive() && this._dayTimeDuration.isPositive(); } compare (other) { if (this.isPositive() && !other.isPositive()) { return 1; } if (!this.isPositive() && other.isPositive()) { return -1; } if (this.equals(other)) { return 0; } const thisMinDays = computeMinDays(this); const thisMaxDays = computeMaxDays(this); const otherMinDays = computeMinDays(other); const otherMaxDays = computeMaxDays(other); if (thisMinDays === otherMinDays && thisMaxDays === otherMaxDays) { const thisSecondsWithoutDays = this.getHours() * 3600 + this.getMinutes() * 60 + this.getSeconds(); const otherSecondsWithoutDays = other.getHours() * 3600 + other.getMinutes() * 60 + other.getSeconds(); if (thisSecondsWithoutDays > otherSecondsWithoutDays) { return 1; } if (thisSecondsWithoutDays < otherSecondsWithoutDays) { return -1; } return 0; } const bothPositive = this.isPositive() && other.isPositive(); if (thisMinDays > otherMaxDays) { return bothPositive ? 1 : -1; } if (thisMaxDays < otherMinDays) { return bothPositive ? -1 : 1; } } toString () { const string = this.isPositive() ? 'P' : '-P'; const TYM = this._yearMonthDuration.toStringWithoutP(); const TDT = this._dayTimeDuration.toStringWithoutP(); if (TYM === '0M') { return string + TDT; } if (TDT === 'T0S') { return string + TYM; } return string + TYM + TDT; } } /** * @static * @param {string} string * @return {?Duration} */ Duration.fromString = function (string) { return new Duration( YearMonthDuration.fromString(string), DayTimeDuration.fromString(string)); }; /** * @static * @param {YearMonthDuration} yearMonthDuration * @return {Duration} */ Duration.fromYearMonthDuration = function (yearMonthDuration) { return new Duration(yearMonthDuration, new DayTimeDuration(yearMonthDuration.isPositive() ? 0 : -0)); }; /** * @static * @param {DayTimeDuration} dayTimeDuration * @return {Duration} */ Duration.fromDayTimeDuration = function (dayTimeDuration) { return new Duration(new YearMonthDuration(dayTimeDuration.isPositive() ? 0 : -0), dayTimeDuration); }; export default Duration;