UNPKG

dmn-processor

Version:

Evaluation of DMN 1.3 decision tables, limited to S-FEEL (Simple Friendly Enough Expression Language)

142 lines (128 loc) 4.75 kB
/* * * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), * Bangalore, India. All Rights Reserved. * */ /* Decision Model and Notation, v1.1 Page : 131-132 */ /* Format : time(from) // from - time string Description : time string convert "from" to time e.g. : time("23:59:00z") + duration("PT2M") = time("00:01:00@Etc/UTC") */ /* Format : time(from) // from - time, date_and_time Description : time, date and time convert "from" to time (ignoring date components) e.g. : time(date and time("2012-12-25T11:00:00Z")) = time("11:00:00Z") */ /* Format : time(hour, minute, second, offset) Description : hour, minute, second, are numbers, offset is a days and time duration, or null creates a time from the given component values e.g. : time(“T23:59:00z") = time(23, 59, 0, duration(“PT0H”)) */ const moment = require('moment-timezone'); const addProperties = require('./add-properties'); const { time_ISO_8601, time_IANA_tz, types, properties } = require('../../helper/meta'); const { duration } = require('./duration'); const { hour, minute, second, 'time offset': time_offset, timezone } = properties; const props = Object.assign({}, { hour, minute, second, 'time offset': time_offset, timezone, type: types.time, isTime: true }); const isNumber = args => args.reduce((prev, next) => prev && typeof next === 'number', true); const parseTime = (str) => { try { const t = moment.parseZone(str, time_ISO_8601); if (t.isValid()) { return t; } throw new Error('Invalid ISO_8601 format time. This is usually caused by an inappropriate format. Please check the input format.'); } catch (err) { throw err; } }; const dtdToOffset = (dtd) => { const msPerDay = 86400000; const msPerHour = 3600000; const msPerMinute = 60000; let d = dtd; if (typeof dtd === 'number') { const ms = Math.abs(dtd); let remaining = ms % msPerDay; const hours = remaining / msPerHour; remaining %= msPerHour; const minutes = remaining / msPerMinute; d = duration(`PT${hours}H${minutes}M`); } if (d.isDtd) { let { hours, minutes } = d; hours = hours < 10 ? `0${hours}` : `${hours}`; minutes = minutes < 10 ? `0${minutes}` : `${minutes}`; return `${hours}:${minutes}`; } throw new Error('Invalid Type'); }; const parseIANATz = (str) => { const match = str.match(time_IANA_tz); if (match) { const [hour, minute, second, tz] = match.slice(1); if (hour && minute && second && tz) { try { const t = moment.tz({ hour, minute, second }, tz); if (t.isValid()) { return t; } throw new Error('Invalid IANA format time. This is usually caused by an inappropriate format. Please check the input format.'); } catch (err) { throw err; } } throw new Error(`Error parsing IANA format input. One or more parts are missing - hour : ${hour} minute : ${minute} second : ${second} timezone : ${tz}`); } return match; }; const time = (...args) => { let t; if (args.length === 1) { const arg = args[0]; if (typeof arg === 'string') { try { t = arg === '' ? moment() : parseIANATz(arg) || parseTime(arg); } catch (err) { throw err; } } else if (typeof arg === 'object') { if (arg instanceof Date) { t = moment.parseZone(arg.toISOString); } else if (arg.isDateTime || arg.isDate) { const str = arg.format(time_ISO_8601); t = moment.parseZone(str, time_ISO_8601); } if (!t.isValid()) { throw new Error('Invalid time. Parsing error while attempting to extract time from date and time.'); } } else { throw new Error('Invalid format encountered. Please specify time in one of these formats :\n- "23:59:00z"\n- "00:01:00@Etc/UTC"\n- date_and_time object'); } } else if (args.length >= 3 && isNumber(args.slice(0, 3))) { const [hour, minute, second] = args.slice(0, 3); t = moment({ hour, minute, second }); const dtd = args[3]; if (dtd) { try { const sign = Math.sign(dtd) < 0 ? '-' : '+'; const offset = `${sign}${dtdToOffset(dtd)}`; t = moment.parseZone(`${moment({ hour, minute, second }).format('THH:mm:ss')}${offset}`, time_ISO_8601); } catch (err) { throw new Error(`${err.message} - the fourth argument in "time" in-built function is expected to be of type "days and time duration"`); } } if (!t.isValid()) { throw new Error('Invalid time. Parsing error while attempting to create time from parts'); } } else { throw new Error('Invalid number of arguments specified with "time" in-built function'); } return addProperties(t, props); }; module.exports = { time };