ifc-expressions
Version:
Parsing and evaluation of IFC expressions
208 lines (207 loc) • 10.1 kB
JavaScript
"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