UNPKG

ifc-expressions

Version:

Parsing and evaluation of IFC expressions

208 lines (207 loc) 10.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.isParsedIfcDateTimeValue = exports.IfcDateTimeValue = void 0; const Types_js_1 = require("../type/Types.js"); const IfcExpressionUtils_js_1 = require("../util/IfcExpressionUtils.js"); const DateFormatException_js_1 = require("../error/value/DateFormatException.js"); const decimal_js_1 = __importDefault(require("decimal.js")); const IfcDateValue_js_1 = require("./IfcDateValue.js"); const IfcTimeValue_js_1 = require("./IfcTimeValue.js"); const IfcTimeStampValue_js_1 = require("./IfcTimeStampValue.js"); class IfcDateTimeValue { constructor(value) { if (typeof value === "string") { var parsed = IfcDateTimeValue.parseIfcDate(value); this.utcDate = parsed.utcDate; this.originalTimeZoneHours = parsed.originalTimeZoneHours; this.originalTimeZoneMinutes = parsed.originalTimeZoneMinutes; this.secondFraction = parsed.secondFraction; this.isLocal = parsed.isLocal; } else if (typeof value === "number" || value instanceof decimal_js_1.default) { let timeStampSeconds = value; if (value instanceof decimal_js_1.default) { timeStampSeconds = value.round().toNumber(); } this.utcDate = new Date(timeStampSeconds); this.originalTimeZoneHours = 0; this.originalTimeZoneMinutes = 0; this.secondFraction = new decimal_js_1.default(0); this.isLocal = false; } else if (value instanceof IfcDateTimeValue) { this.utcDate = value.utcDate; this.originalTimeZoneMinutes = value.originalTimeZoneMinutes; this.originalTimeZoneHours = value.originalTimeZoneHours; this.secondFraction = value.secondFraction; this.isLocal = value.isLocal; } else if (isParsedIfcDateTimeValue(value)) { this.utcDate = value.utcDate; this.secondFraction = value.secondFraction; this.originalTimeZoneHours = value.originalTimeZoneHours; this.originalTimeZoneMinutes = value.originalTimeZoneMinutes; this.isLocal = value.isLocal; } this.stringRepresentation = this.toCanonicalString(); } static parseIfcDate(value) { decimal_js_1.default.set({ defaults: true }); let match = value.match(this.regex); if ((0, IfcExpressionUtils_js_1.isNullish)(match)) { throw new DateFormatException_js_1.DateFormatException("Not an IfcDateTime: " + value); } let [wholeString, year, month, day, hours, minutes, seconds, fractionSeconds, timeZoneWhole, timeZoneSign, timeZoneHours, timeZoneMinutes,] = match; var utcDate = new Date(0); utcDate.setUTCFullYear(Number.parseInt(year)); utcDate.setUTCMonth(Number.parseInt(month) - 1); utcDate.setUTCDate(Number.parseInt(day)); utcDate.setUTCHours(Number.parseInt(hours)); utcDate.setUTCMinutes(Number.parseInt(minutes)); utcDate.setUTCSeconds(Number.parseInt(seconds)); const secondFraction = (0, IfcExpressionUtils_js_1.isNullish)(fractionSeconds) ? new decimal_js_1.default("0") : new decimal_js_1.default("0" + fractionSeconds); //arbitrary precision fractions (to the precision of Decimal.precision) const originalZoneSign = (0, IfcExpressionUtils_js_1.isNullish)(timeZoneSign) ? 0 : timeZoneSign === "+" ? 1 : -1; const originalTimeZoneHours = originalZoneSign * ((0, IfcExpressionUtils_js_1.isNullish)(timeZoneHours) ? 0 : Number.parseInt(timeZoneHours)); const originalTimeZoneMinutes = originalZoneSign * ((0, IfcExpressionUtils_js_1.isNullish)(timeZoneMinutes) ? 0 : Number.parseInt(timeZoneMinutes)); const isLocal = (0, IfcExpressionUtils_js_1.isNullish)(timeZoneWhole); utcDate.setUTCHours(utcDate.getUTCHours() - originalTimeZoneHours); utcDate.setUTCMinutes(utcDate.getUTCMinutes() - originalTimeZoneMinutes); return { utcDate, secondFraction, originalTimeZoneHours, originalTimeZoneMinutes, isLocal, }; } static of(value) { return new IfcDateTimeValue(value); } getTimeAsString() { const fraction = (0, IfcExpressionUtils_js_1.isNullish)(this.secondFraction) ? "" : this.secondFraction.isZero() ? "" : this.secondFraction.toString().substring(1); return `${this.pad00(this.utcDate.getUTCHours() + this.originalTimeZoneHours)}:${this.pad00(this.utcDate.getUTCMinutes() + this.originalTimeZoneMinutes)}:${this.pad00(this.utcDate.getUTCSeconds())}${fraction}`; } pad00(num) { return ("" + num).padStart(2, "0"); } getDateAsString() { return `${this.utcDate.getUTCFullYear()}-${this.pad00(this.utcDate.getUTCMonth() + 1)}-${this.pad00(this.utcDate.getUTCDate())}`; } getTimeZoneAsString() { if (this.isLocal) { return ""; } if (this.originalTimeZoneMinutes === 0 && this.originalTimeZoneHours === 0) { return "Z"; } const sign = this.originalTimeZoneHours >= 0 && this.originalTimeZoneMinutes >= 0 ? "+" : "-"; return `${sign}${this.pad00(Math.abs(this.originalTimeZoneHours))}:${this.pad00(Math.abs(this.originalTimeZoneMinutes))}`; } getTimeStampSeconds() { const offset = this.isLocal ? new Date().getTimezoneOffset() * 60 : 0; return new decimal_js_1.default(this.utcDate.getTime()).divToInt(1000).minus(offset); } getTime() { const offset = this.isLocal ? new Date().getTimezoneOffset() * 60 : 0; return new decimal_js_1.default(this.utcDate.getTime()) .minus(offset) .plus(this.secondFraction); } getValue() { return this; } getType() { return Types_js_1.Type.IFC_DATE_TIME; } static isIfcDateTimeValueType(arg) { return (arg instanceof IfcDateTimeValue || (!(0, IfcExpressionUtils_js_1.isNullish)(arg.stringRepresentation) && !(0, IfcExpressionUtils_js_1.isNullish)(arg.stringRepresentation.match(IfcDateTimeValue.regex)))); } static isValidStringRepresentation(str) { return this.regex.test(str); } equals(other) { return (IfcDateTimeValue.isIfcDateTimeValueType(other) && this.getTime().eq(other.getTime())); } toCanonicalString() { return (this.getDateAsString() + "T" + this.getTimeAsString() + this.getTimeZoneAsString()); } toString() { return this.stringRepresentation; } compareTo(other) { return decimal_js_1.default.sign(this.getTime().minus(other.getTime())); } static ofTimeStampSeconds(timeStampSeconds) { var timeStampMillis = timeStampSeconds; if (timeStampSeconds instanceof decimal_js_1.default) { timeStampMillis = timeStampSeconds.round().toNumber(); } timeStampMillis = timeStampMillis * 1000; return new IfcDateTimeValue(timeStampMillis); } toIfcDateValue() { return IfcDateValue_js_1.IfcDateValue.of(this.getDateAsString() + this.getTimeZoneAsString()); } toIfcTimeValue() { return IfcTimeValue_js_1.IfcTimeValue.of(this.getTimeAsString() + this.getTimeZoneAsString()); } toIfcTimeStampValue() { return IfcTimeStampValue_js_1.IfcTimeStampValue.of(this.getTimeStampSeconds()); } addDuration(duration) { const resultDate = new Date(this.utcDate.getTime()); const accumulatedFractions = this.secondFraction.add(duration.getFractionAsSeconds()); const newSecondFraction = accumulatedFractions.minus(accumulatedFractions.divToInt(1)); resultDate.setUTCSeconds(resultDate.getUTCSeconds() + accumulatedFractions.divToInt(1).toNumber()); resultDate.setUTCSeconds(resultDate.getUTCSeconds() + duration.getSeconds().divToInt(1).toNumber()); resultDate.setUTCMinutes(resultDate.getUTCMinutes() + duration.getMinutes().divToInt(1).toNumber()); resultDate.setUTCHours(resultDate.getUTCHours() + duration.getHours().divToInt(1).toNumber()); resultDate.setUTCDate(resultDate.getUTCDate() + duration.getDays().divToInt(1).toNumber()); resultDate.setUTCDate(resultDate.getUTCDate() + duration.getWeeks().divToInt(1).times(7).toNumber()); resultDate.setUTCMonth(resultDate.getUTCMonth() + duration.getMonths().divToInt(1).toNumber()); resultDate.setUTCFullYear(resultDate.getUTCFullYear() + duration.getYears().divToInt(1).toNumber()); return new IfcDateTimeValue({ utcDate: resultDate, secondFraction: newSecondFraction, originalTimeZoneHours: this.originalTimeZoneHours, originalTimeZoneMinutes: this.originalTimeZoneMinutes, isLocal: this.isLocal, }); } } exports.IfcDateTimeValue = IfcDateTimeValue; IfcDateTimeValue.regex = /^([+\-]?(?:[1-9]\d*)?\d{4}(?<!0000))-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|(?<=23:59:)60)(\.\d+)?(Z|([+\-])(0[0-9]|1[0-2])(?::?([0-5][0-9]))?)?$/; function isParsedIfcDateTimeValue(arg) { return (!(0, IfcExpressionUtils_js_1.isNullish)(arg.utcDate) && !(0, IfcExpressionUtils_js_1.isNullish)(arg.secondFraction) && !(0, IfcExpressionUtils_js_1.isNullish)(arg.originalTimeZoneHours) && !(0, IfcExpressionUtils_js_1.isNullish)(arg.originalTimeZoneMinutes) && !(0, IfcExpressionUtils_js_1.isNullish)(arg.isLocal)); } exports.isParsedIfcDateTimeValue = isParsedIfcDateTimeValue; //# sourceMappingURL=IfcDateTimeValue.js.map